ㆍ2010년에 썬이 오라클에 인수되어서 현재 Java의 저작권자는 오라클이며, 2019년 1월부터 유료화되었다.
단, Java EE는 이클립스 재단의 소유이다.
Java 버전별 특징
Java 12
ㆍ2019.03
ㆍ문법적으로 Switch문 확장
switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
System.out.println(6);
break;
case TUESDAY:
System.out.println(7);
break;
case THURSDAY:
case SATURDAY:
System.out.println(8);
break;
case WEDNESDAY:
System.out.println(9);
break;
}
예전에는 이렇게 써야 했던 Switch문을 아래와 같은 형식으로도 쓸 수 있게 되었다.
1.
2.
3.
4.
5.
6.
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
case TUESDAY -> System.out.println(7);
case THURSDAY, SATURDAY -> System.out.println(8);
case WEDNESDAY -> System.out.println(9);
}
ㆍ이외에 가비지 컬렉터 개선, 마이크로 벤치마크 툴 추가, 성능 개선
Java 11
ㆍ2018.09
ㆍ일반 지원은 2023년 9월, 연장 지원은 2026년 9월에 종료될 예정이다.
ㆍ이클립스 재단으로 넘어간 Java EE가 JDK에서 삭제되고, JavaFX도 JDK에서 분리되어 별도의 모듈로 제공된다.
ㆍ람다 파라미터에 대한 지역변수 문법 : (var x, var y) -> x.process(y) => (x, y) -> x.process(y)
IntStream.of(1, 2, 3)
.filter((var i) -> i % 2== 0)
.forEach(System.out::println);
IntStream.of(1, 2, 3)
.filter(i -> i % 2== 0)
.forEach(System.out::println);
ㆍHTTP 클라이언트 표준화 기능 추가 : Java 9, 10에 사용되었던 jdk.incubator.http 패키지가 표준화되어 java.net.http 패키지로 추가
ㆍ네스트 기반 액세스 컨트롤(Nest-based access controls)
액세스 가능성을 확장하는 브릿지 메소드 삽입 지원 컴파일러의 필요성 제거
ㆍ다이나믹 클래스-파일 콘스탄스(Dynamic class-file constans)
새로운 형태의 구체화 가능한 클래스파일 상수를 만드는데 요구되는 비용과 간섭을 줄이고, 표현력과 성능을 위한 보다 다양한 옵션 제공
ㆍ엡실론(Epsilon) 가지비 컬렉터 : 오버헤드의 최저지연과 할당 제한이 가능한 완전한 수동 가비지 컬렉터 적용
엡실론은 테스트 전용으로 설계된, 아무 일도 안하는 시험 수집기이다. 실제로 가비지 컬렉션(수집) 활동을 일체 하지 않는다. 따라서 엡실론이 시행되는 동안 할당된 힙 메모리는 한 바이트, 한 바이트가 사실상 메모리 누수이다. 절대 회수할 수 없는 메모리여서 JVM은 결국 언젠가(단시간 내에) 메모리가 고갈되어 멎게 된다. 때문에 운영계 환경에서 절대 사용 금문인 수집기이다.
즉, 메모리 할당만 처리하고 실제로 메모리는 전혀 회수하지 않는 GC이다. 사용 가능한 Java Heap이 고갈되면 JVM을 셧다운 시킨다. 때문에 다음과 같은 작업에 유리하다.
-테스트 및 마이크로벤치마크 수행
-회귀 테스트
-할당률이 낮거아 0인 자바 애플리케이션 또는 라이브러리 코드의 테스트
(출처 : 자바 최적화: 가장 빠른 성능을 구현하는 검증된 10가지 기법)
ㆍThe Z Garbage Collector(ZGC) : 대기 시간이 낮은 확장 가능한(Scalable Low-Latency) GC이다.
메모리를 자동으로 정리해주는 가비지 컬렉터는 자바의 장점 중 하나이지만, 가비지 컬렉터가 동작할 때 JVM이 애플리케이션을 멈추기 때문에(stop-the-world) 자바의 단점이기도 합니다. ZGC는 이 시간을 10ms(millisecond) 미만으로 줄이고 15% 이하의 성능 페널티를 목표로 합니다.
- stop-the-world 시간이 10ms 미만이기 때문에 대기 시간이 짧다(low latency).
- 모든 작업을 동시에(concurrently) 작업하며, 애플리케이션 스레드의 실행을 중지시키지 않는다.
- 위와 같은 이유로, ZGC는 10ms 미만의 짧은 대기 시간이 필요하거나 테라 바이트 큐모의 매우 큰 heap을 사용하는 애플리케이션을 위한 GC이다.
ㆍ플라이트 레코더(Flight Recorder) : 자바 애플리케이션과 핫스팟 JVM의 오류 해결을 위한 낮은 오버헤드 데이터 수집 프레임워크 제공
ㆍ가장 커다란 변화는 바로 라이센스 부분.
Java 11부터 Oracle JDK의 독점기능이 오픈소스 버전인 OpenJDK에 이식된다. 이는 다시말해 Oracle JDK와 OpenJDK가 완전히 동일해진다는 뜻
Oracle JDK는 Java11부터 LTS(장기지원) 버전으로 3년마다 출시, 출시 후 5년 동안 오라클의 기술지원이 제공되며 최대 3년까지 지원기간 연장가능
Oracle JDK는 이제 3년에 한 번 출시되니 Java의 실질적인 버전 업을 담당하는 것은 OpenJDK가 된 셈이다.
OpenJDK는 기업들을 위한 기술 지원은 없고, 새로운 버전이 나오면 이전 버전에 대한 마이너 업데이트와 보안 업데이트는 중단된다.
그리고 Java 11과 함께 발표된 또 다른 소식은 바로 Oracle JDK가 구독형 유료 모델로 전환된다는 점이다. # 2019년 1월부터 오라클이 제공하는 모든 JDK는 유료화되며, 구독권을 구입하지 않으면 JDK에 접근 자체가 금지된다. 기존의 일반/연장 지원 서비스는 구독권에 포함되므로 별도의 서비스로는 제공되지 않는다. 개인 사용자는 2021년 1월부터 비용을 지불해야 한다. 이 때문에 많은 기업들이 Oracle JDK에서 발을 빼고 있으며, OpenJDK를 기반으로 한 다른 서드파티 JDK가 대안으로 떠오르고 있다.
인스턴스 생성시 Generics를 양쪽에 선언해줬어야 했는데 다이아몬드 연산자인 <> 사용으로 대체 가능하다. 다시 말해, 제너릭 타입 파라미터를 선언과 생성시 중복해서 써야했었다.
이전 버전
Map<String, Object> user = new HashMap<String, Object>();
Java 7 버전
Map<String, Object> user = new HashMap<> ();
2. String in Switch
Switch문에서 문자열 사용 가능
switch (day) {
case"NEW":
System.out.println("Order is in NEW state");
break;
case"CANCELED":
System.out.println("Order is Cancelled");
break;
case"REPLACE":
System.out.println("Order is replaced successfully");
break;
case"FILLED":
System.out.println("Order is filled");
break;
default:
System.out.println("Invalid");
}
3. Automatic Resource Management
Java 7 이전에는 DB Connection, File Stream을 open했을 때 예기치 못한 오류 발생시 정상적인 종료를 위해 finally block에서 close처리를 반드시 해야 했지만 Java 7 에서는 try with resource 구문이 추가되어 자동으로 자원들을 close한다. 이러한 메커니즘을 사용하기 위해서는 AutoClosable, Closeable 인터페이스를 구현해야 한다. Java 7의 Streams, Files, Socket, DB Connection등은 해당 인터페이스를 구현하고 있다. Java 7 이전
publicstaticvoidmain(String args[]){
FileInputStream fin = null;
BufferedReader br = null;
try {
fin = new FileInputStream("info.xml");
br = new BufferedReader(new InputStreamReader(fin));
if (br.ready()) {
String line1 = br.readLine();
System.out.println(line1);
}
} catch (FileNotFoundException ex) {
System.out.println("Info.xml is not found");
} catch (IOException ex) {
System.out.println("Can't read the file");
} finally {
try {
if (fin != null)
fin.close();
if (br != null)
br.close();
} catch (IOException ie) {
System.out.println("Failed to close files");
}
}
}
Java 7
publicstaticvoidmain(String args[]){
try (FileInputStream fin = new FileInputStream("info.xml");
BufferedReader br = new BufferedReader(new InputStreamReader(
fin));) {
if (br.ready()) {
String line1 = br.readLine();
System.out.println(line1);
}
} catch (FileNotFoundException ex) {
System.out.println("Info.xml is not found");
} catch (IOException ex) {
System.out.println("Can't read the file");
}
}
4. Fork/Join Framework
fork/join framework는 멀티프로세서의 성능을 이용할 수 있는 ExecutorService인터페이스의 구현체이다. 반복적으로 작은 조각으로 작업을 나누어 수행 할 수 있게 설계되어있다. 어플리케이션의 성능을 향상 시키기 위해 가능한 모든 프로세서를 이용하는 것으로 ExecutorService 인터페이스를 Implement하는 것으로 fork/join 프레임워크는 ThreadPool내 WorkerThread에게 작업들을 분배한다. fork/join framework는 생산자-소비자 알고리즘(Produce-Consumer Algorithems)과는 다른 work-stealing algorithems을 사용한다. 일이 없는 WorkerThread는 작업중인 다른 Thread의 작업을 훔쳐 올 수 있다. fork/join framework의 핵심은 AbstractExecutorService를 구현한 ForkJoinPool클래스이다. ForkJoinPool은 중요 메커니즘인 work-stealing algorithems을 구현하고 ForkJoinTask 프로세스들을 실행 할 수 있다. RecursiveTask 또는 RecursiveAction과 같은 ForkJoinTask 하위클래스를 랩핑할 수 있다.