자바8 나머지 공개
DESCRIPTION
지난 26일(2014/7/26), 지앤선과 KSUG가 함께 진행했던 세미나 마지막 시간에 발표한 내용입니다. 자바 8 개선 사항 중에서 람다와 스트림 API를 제외한 나머지 중에 개발자들이 관심 둘만한 몇가지를 골라서 요약했습니다.TRANSCRIPT
박성철
나머지자바 8
람다
이야기
SK Planet, 한국 스프링 사용자 모임(KSUG)
를 제외한
박성철(fupfin)
노땅 개발자(라고 착각하는 관리자)
엄청 망해봤어요
산만해요
새 날짜 APIDate API
기존 날짜와 시간 API
쓰레드에서 안전하지 않음사용하기 불편, Date? Calendar?일관성이 떨어짐어정쩡한 Unixtime의 추상화불규칙한 성능헬로월드 “Java의 날짜와 시간 API” 참고 http://helloworld.naver.com/helloworld/645609
오픈소스 joda-time이 사실상 표준으로 사용
새 API의 목표
일관된 API쓰레드에서 안전, 불변값직관적이고 사용하기 편한 APILocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).minusDays(2)관련 표준 준수: ISO-8601, CLDR(Unicode Common Locale Data Repository), TZDB( Time-Zone Database)UTC와 연계된 명시적 시간 척도joda-time 참조도메인 객체, 타입 안전:DayOfWeek,����������� ������������������ HijrahDate,����������� ������������������ HijrahEra,����������� ������������������ Instant,����������� ������������������ IsoEra,����������� ������������������ JapaneseDate,����������� ������������������ JapaneseEra,����������� ������������������ LocalDate,����������� ������������������ LocalDateTime,����������� ������������������ LocalTime,����������� ������������������ MinguoDate,����������� ������������������ MinguoEra,����������� ������������������ Month,����������� ������������������ MonthDay,����������� ������������������ OffsetDateTime,����������� ������������������ OffsetTime,����������� ������������������ ThaiBuddhistDate,����������� ������������������ ThaiBuddhistEra,����������� ������������������ Year,����������� ������������������ YearMonth,����������� ������������������ ZonedDateTime,����������� ������������������ ZoneOffset
LocalDate, LocalTime
LocalDate: 특정 지역의 날짜, 시간대 정보 제외LocalTime: 특정일의 시간, 시, 분, 초, 나노(10-9)초 LocalDateTime으로 날짜와 시간 결합 가능다양한 날짜 연산 메서드 제공
생성
현재:LocalDateTime.now()����������� ������������������ 특정일:LocalDate.of(2014,����������� ������������������ Month.JULY,����������� ������������������ 26)unix 시간: LocalDate.ofEpochDay(1406321656)����������� ������������������ 시간:����������� ������������������ LocalTime.of(10,����������� ������������������ 30,����������� ������������������ 50);
LocalDate, LocalTime
날짜 연산
with____: 특정 날짜 요소만 변경LocalDateTime.now().withYear(1980)
plus____/minus____: 상대적인 날짜/시간 계산 LocalDateTime.now().plusDays(-10)기간을 나타내는 도메인 객체:����������� ������������������ Duration,����������� ������������������ Period
until____: 기간 계산 start.until(LocalDateTime.now());기간을 나타내는 도메인 객체:����������� ������������������ Duration,����������� ������������������ Period
시간대
ZoneId/ZoneOffsetZoneID: 지역 기반 시간대 표시ZoneId.of(“Asia/Seoul”)
LocalDateTime + 시간대LocalDateTime.now().atZone(ZoneId.of(“Asia/Seoul”))
ZoneOffset: 고정 상대값ZoneOffset.of("+9:00")
ZonedDateTime
LocalDateTime/LocalTime + 시간대 시차LocalDateTime.now().atOffset(ZoneOffset.of("+9:00"))
OffsetDateTime/OffsetTime
JDBC 날짜/시간 개선
SQL Java 8
날짜 DATE LocalDate
시간 TIME LocalTime
일시 TIMESTAMP LocalDateTime
시간 + 시간대 TIME WITH TIMEZONE OffsetTime
일시 + 시간대 TIMESTAMP WITH TIMEZONE OffsetDateTime
동시성 개선concurrency
ConcurrentHashMap
computeIfAbsent/computeIfPresent값의 존재 유무에 따라 람다 표현 수행다양한 forEach() 변종 메서드forEach,����������� ������������������ forEachKey,����������� ������������������ forEachValue,����������� ������������������ forEachEntry탐색 메서드search,����������� ������������������ searchKeys,����������� ������������������ searchValues,����������� ������������������ searchEntries환산(Reduction) 메서드용reduce,����������� ������������������ reduceToDouble,����������� ������������������ reduceToLong
람다 관련 편의 메서드 추가
mappingCount(): long 버전의 size()newKeySet(): concurrentHashMap 기반의 Set 생성
기타
java.util.concurrent.atomic
AtomicBoolean,����������� ������������������ AtomicInteger,����������� ������������������ AtomicLong,����������� ������������������ AtomicReference 등
동시성 환경에서 원자적으로 처리되는 값 표현 객체
누산기: DoubleAccumulator,����������� ������������������ LongAccumulator계수기: DoubleAdder,����������� ������������������ LongAdder
기존 원자적으로 갱신되는 값 객체
새로 추가된 고성능 누산/계수기
- Java 8 Performance Improvements: LongAdder vs AtomicLong: http://skpla.net/fQAB- Java 8 Concurrency: LongAdder: http://skpla.net/dZfC
LongAdder의 성능 밴치 마크
ForkJoinPool
Java 7에 추가된 ExecutorService 구현체범용 최적화 공용 풀 추가: ForkJoinPool.commonPool()성능 개선병렬처리스트림(Parallel Stream) 구현에 사용Arrays.parallelSort(…)에 사용
Is Java 8 the fastest JVM ever? Performance benchmarking of Fork-Join: http://skpla.net/cZSO
성능 밴치 마크
StampedLockjava.util.concurrent.locks.StampedLock기존 읽기/쓰기 동시성을 향상을 위해 개발된 ReadWriteLock의 성능 문제 개선읽기, 쓰기 외 낙관적 락(Optimistic Lock) 추가낙관적 락은 쓰기보다 읽기가 많을 때 ReadWriteLock보다 100여배까지 빠름
long����������� ������������������ stamp����������� ������������������ =����������� ������������������ lock.tryOptimisticRead();����������� ������������������ !read();����������� ������������������ ����������� ������������������ ����������� ������������������ if(!lock.validate(stamp)){����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ long����������� ������������������ stamp����������� ������������������ =����������� ������������������ lock.readLock();����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ try����������� ������������������ {����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ read();����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ }����������� ������������������ finally����������� ������������������ {����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ lock.unlock(stamp);����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ }����������� ������������������ }
메타 프로그래밍 지원 개선meta programming
어노테이션 중복 지정 가능
자바5에서 자바 7까지 어노테이션 중복 지정 불가
자바 8에서는 중복 지정 가능, 암시적 컨테이너 어노테이션 적용@ContainedBy,����������� ������������������ @ContainerFor
@Foo(1)����������� ������������������ @Foo(2)����������� ������������������ //����������� ������������������ error:����������� ������������������ Duplicate����������� ������������������ annotation����������� ������������������ class����������� ������������������ SomeClass{}����������� ������������������ !@Foos({@Foo(1),����������� ������������������ @Foo(2)})����������� ������������������ class����������� ������������������ SomeClass{}
컨테이너 어노테이션을 사용해서 제약 우회
@Foo(1),����������� ������������������ @Foo(2)����������� ������������������ class����������� ������������������ SomeClass{}
@ContainedBy(Foos.class)����������� ������������������ @interface����������� ������������������ Foo����������� ������������������ {����������� ������������������ int����������� ������������������ value();����������� ������������������ }����������� ������������������ !@ContainerFor(Foo.class)����������� ������������������ @interface����������� ������������������ Foos����������� ������������������ {����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ Foo[]����������� ������������������ value();����������� ������������������ }
@interface����������� ������������������ Foo����������� ������������������ {����������� ������������������ int����������� ������������������ value();����������� ������������������ }����������� ������������������ !@interface����������� ������������������ Foos����������� ������������������ {����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ Foo[]����������� ������������������ value();����������� ������������������ }
매개변수 메타데이터 리플랙션 지원
자바7까지, 생성자와 메서드의 매개변수 정보를 바이트 코드에서 삭제매개변수 타입 정보 외에는 리플랙션을 통해서 얻을 수 없었음자바 8에 java.lang.reflect.Executable.getParameters() 추가 Executable은 Method와 Constructor의 부모-parameters 컴파일러 옵션으로 활성화매개변수 메타 데이터: Parameter 어노테이션 정보, 수정자, 이름, 타입, 가변인자 여부
자바 타입 어노테이션
JSR308자바8부터 타입에도 어노테이션 지정 가능 클래스 인스턴스 생성, 타입 캐스팅, 인터페이스 구현 등에서 사용컴파일러에 타입 확인 프로세서를 추가해서 처리Checker Framework: http://types.cs.washington.edu/checker-framework/자바의 타입 시스템보다 강화된 타입 확인 가능
@NotNull����������� ������������������ String����������� ������������������ notNullString����������� ������������������ =����������� ������������������ ...����������� ������������������ @Email����������� ������������������ String����������� ������������������ email����������� ������������������ =����������� ������������������ ...����������� ������������������ @NotNull����������� ������������������ @NotBlank����������� ������������������ String����������� ������������������ notEmptyString����������� ������������������ =����������� ������������������ ...
new����������� ������������������ @Interned����������� ������������������ MyObject()����������� ������������������ new����������� ������������������ @NonEmpty����������� ������������������ @Readonly����������� ������������������ List<String>(myNonEmptyStringSet)
myString����������� ������������������ =����������� ������������������ (@NonNull����������� ������������������ String)����������� ������������������ myObject;����������� ������������������ query����������� ������������������ =����������� ������������������ (@Untainted����������� ������������������ String)����������� ������������������ str;
변수 선언
객체 생성
타입 캐스팅
기타Etc.
나즈혼(Nashorn)자바스크립트 엔진
구형 리노(Rhino)를 대체하는 기본 자바스크립트 엔진자바 객체 호출 가능자바 7의 invokedynamic 활용, 성능 향상
$����������� ������������������ $JAVA_HOME/bin/jjs����������� ������������������ jjs>����������� ������������������ print('Hello����������� ������������������ World');
ScriptEngine����������� ������������������ engine����������� ������������������ =����������� ������������������ new����������� ������������������ ScriptEngineManager().getEngineByName("nashorn");����������� ������������������ engine.eval("print('Hello����������� ������������������ World!');");
자바의 스크립트 엔진 매니저를 사용해 실행
터미널에서 jjs 명령을 사용해 실행
Nashorn: The New Rhino on the Block: http://skpla.net/ggNQPerformance: Nashorn vs. Node : http://skpla.net/e9f4
성능 밴치마크
java.nio.file.Files
Files.lines(“/to/my/text/file.txt”).filter(s����������� ������������������ ->����������� ������������������ s.length()����������� ������������������ >����������� ������������������ 255).count();
!Files.lines(Path, Charset): 파일을 한 줄씩 읽어 Stream으로 반환Files.lines(Path): lines(Path, Charset)과 동일, UTF-8 사용각종 편의 메서드:Files.readAllLines(Path), Files.newBufferedReader(Path), Files.newBufferedWriter(Path,OpenOption...), Files.write(Path,Iterable,OpenOption...)
Base64
String����������� ������������������ asB64����������� ������������������ =����������� ������������������ Base64.getEncoder()����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ .encodeToString(“some����������� ������������������ string".getBytes("utf-8"));����������� ������������������ System.out.println(asB64);����������� ������������������ //����������� ������������������ “c29tZSBzdHJpbmc=“����������� ������������������ !byte[]����������� ������������������ asBytes����������� ������������������ =����������� ������������������ Base64.getDecoder().decode("c29tZSBzdHJpbmc=");����������� ������������������ System.out.println(new����������� ������������������ String(asBytes,����������� ������������������ "utf-8"));����������� ������������������ //����������� ������������������ “some����������� ������������������ string”
기본 Base64 인코딩/디코딩 지원
String����������� ������������������ urlEncoded����������� ������������������ =����������� ������������������ Base64.getUrlEncoder()����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ ����������� ������������������ .encodeToString("subjects?abcd".getBytes("utf-8"));����������� ������������������ System.out.println("Using����������� ������������������ URL����������� ������������������ Alphabet:����������� ������������������ "����������� ������������������ +����������� ������������������ urlEncoded);����������� ������������������ //c3ViamVjdHM_YWJjZA==
URL 인코딩/디코딩, ‘+‘ -> ‘-’, ‘/‘ -> ‘_’
MIME 인코딩/디코딩 지원, 76자 단위로 개행
byte[]����������� ������������������ toEncode����������� ������������������ =����������� ������������������ …⋯����������� ������������������ //매우����������� ������������������ 긴����������� ������������������ 문자열����������� ������������������ String����������� ������������������ mimeEncoded����������� ������������������ =����������� ������������������ Base64.getMimeEncoder().encodeToString(toEncode);����������� ������������������ System.out.println(mimeEncoded);����������� ������������������ !NDU5ZTFkNDEtMDVlNy00MDFiLTk3YjgtMWRlMmRkMWEzMzc5YTJkZmEzY2YtM2Y2My00Y2Q4LTk5����������� ������������������ ZmYtMTU1NzY0MWM5Zjk4ODA5ZjVjOGUtOGMxNi00ZmVjLTgyZjctNmVjYTU5MTAxZWUyNjQ1MjJj����������� ������������������ NDMtYzA0MC00MjExLTk0NWMtYmFiZGRlNDk5OTZhMDMxZGE5ZTYtZWVhYS00OGFmLTlhMjgtMDM1
END_OF_FOURTH_WAVE
잘못했어요.
용서해 주세요.