1. 어떤 자바 버전을 사용해야 할까?
- 기업의 기존 프로젝트에서는 Java 8을 사용해야 하는 경우가 많음
- 일부 레거시 프로젝트는 Java 1.5(2004년 출시) 또는 1.6(2006년 출시)에서 중단되기도 함
- 최신 IDE, 프레임워크 및 빌드 도구를 사용하고 그린 필드 프로젝트를 시작하는 경우 Java 11(LTS) 또는 최신 Java 17 LTS를 망설임 없이 사용할 수 있다.
- 안드로이드 개발의 특별한 분야가 있는데, 자바 버전은 기본적으로 자바 7에 고정되어 있고, 특정한 자바 8 기능들을 이용할 수 있다. 또는 코틀린 프로그래밍 언어를 사용하는 것으로 전환
2. 특정 자바 버전을 학습해야 할까?
12, 17와 같은 특정 Java 버전만을 "학습"할 필요가 없다.
Python 2에서 3과 같이 릴리스 사이에 심각한 문제가 있는 것과 달리 자바는 하위 호환성이 매우 높기 때문
- 즉, Java 5 또는 8 프로그램이 Java 8-17 가상 머신에서 실행되도록 보장된다.
- 이걸 backward compatible (하위 호환성) 이라 한다.
반대로 java 8 JVM에서는 사용할 수 없는 java 17 기능을 의존한다면 컴파일 되지 않는다.
- 대부분 java.lang.UnsupportedClassVersionError 발생
그러므로 오히려 Java 8의 내용들로 토대를 쌓고 Java 9-17에 추가된 기능에 대해 알아보고 언제든지 사용할 수 있다.
3. 자바 Distribution
JDK 다운로드를 제공하는 다양한 사이트가 있으며 "누가 어떤 라이선스로 무엇을 제공하는지"가 불분명하다.
OpenJDK 프로젝트
Java 소스 코드(RE/JDK의 소스 코드)의 경우 OpenJDK 프로젝트 사이트에 존재하는 유일한 소스 코드
그러나 이것은 소스 코드일 뿐 배포 가능한 빌드가 아니다.
- 이론적으로, 해당 소스 코드로 빌드를 만들 수 있다
- 예를 들어 MarcoJDK라고 부르며 배포하기 시작 가능
- 하지만 합법적으로 자바 SE 호환이라고 부를 수 있는 우리의 배포판은 인증이 부족할 것
이러한 이유로 실제로 이러한 빌드를 만들고 인증을 받은 후 배포하는 벤더가 많지 않다.
OpenJDK 빌드(오라클) 및 OracleJDK 빌드
자바를 소스에서 빌드하는 벤더 중 하나가 오라클이다.
Oracle JDK와 OpenJDK의 차이점이다.
- Oracle JDK는 상용(유료)이지만, OpenJDK는 오픈소스기반(무료)
- Oracle JDK의 라이선스는 Oracle BCL(Binary Code License) Agreement이지만, OpenJDK의 라이선스는 Oracle GPL v2
- Oracle JDK는 LTS(장기 지원) 업데이트 지원을 받을 수 있지만, OpenJDK는 LTS 없이 6개월마다 새로운 버전이 배포된다.
- Oracle JDK는 Oracle이 인수한 Sun Microsystems 플러그인을 제공하지만, OpenJDK는 제공하지 않는다.
- Oracle JDK는 OpenJDK 보다 CPU 사용량과 메모리 사용량이 적고, 응답시간이 높다.
Java 8 이전 OpenJDK 빌드와 OracleJDK 빌드 사이에는 실제 소스 차이가 존재했는데, 최신의 두 버전은 본질적으로 동일하며 약간의 차이만 존재한다.
Adoptium (formerly AdoptOpenJDK)
2017년에 자바 유저 그룹 멤버, 개발자, 벤더(아마존, 마이크로소프트, 피보탈, 레드햇 등)로 구성된 그룹이 AdoptOpenJDK라는 커뮤니티를 시작
- 참고: 2021년 8월 현재, AdoptOpenJDK 프로젝트는 새로운 집으로 옮겨졌고 지금은 Eclipse Adoptium 프로젝트로 불린다.
또한 보다 긴 가용성/업데이트를 갖춘 강력한 무료 OpenJDK 빌드를 제공하며 다음과 같은 두 가지 Java 가상 머신도 선택 가능
Java를 설치하려는 경우 권장된다.
Azul Zulu, Amazon Corretto, SAPMachine
- 그 외에 주목할만한 distribution
4. JAVA 버전별 특징
JDK 1.0a2(1995년 5월)
1. 언어 자체가 정식으로 발표된 날이기도 합니다.
2. Oak라는 명칭으로 불리었습니다.
JDK 1.0(1996년 1월)
1. 안정화 작업을 거친 1.0.2 버전에서 Java로 이름이 바뀌었습니다.
JDK 1.1(1997년 2월)
1. 이너 클래스(Inner Class), JavaBeans, RMI, 리플렉션(Reflection), Calendar 유니코드 지원 등이 추가되었습니다.
JavaBeans 란?
JavaBeans는 자바로 작성된 소프트웨어 컴포넌트를 지칭합니다.
Beans 규약
1. 기본 생성자가 반드시 존재해야 한다.
2. 모든 속성은 비공개이다.
3. 속성에 접근하고 꺼내올 수 있는 getter, setter 메서드를 구성한다.
4. Serializable을 구현한다.
RMI 란?
Remote Method Invocation의 약자로 분산 애플리케이션을 구축하는 데 사용됩니다.
한 시스템(JVM)에 상주하는 객체가 다른 JVM에서 실행 중인 객체에 액세스, 호출할 수 있도록 도와주는 메커니즘입니다. 코드에서는 java.rmi 패키지를 통하여 제공됩니다.
J2SE 1.2(1998년 12월)
1. Swing GUI, JIT, Collection Framework 등의 굵직한 기능이 추가되었습니다.
2. 2부터 약칭을 J2SE(Java 2 Standard Edition)로 표기하기 시작했으며, 이 표기는 5까지 사용됩니다.
J2SE 1.3(2000년 3월)
1. HotSpot JVM, JNDI, JPDA, JavaSound 등이 추가되었습니다.
J2SE 1.4(2002년 2월)
1. assert, 정규표현식, IPv6, XML API, JCE, JSSE, JAAS, Java Web Start 등이 추가되었습니다.
J2SE 5(2004년 9월)
기능 변화
1. 이때부터 버전 중 앞의 1을 빼버리고 표기하기 시작했습니다.
2. Generics
5 버전의 가장 중요한 신규 기능입니다. 기존에 컬렉션프레임워크를 이용하여 발생할 수 있는 ClassCastException을 컴파일 시간에 검증할 수 있습니다. 이러한 컴파일 검증 기능뿐만 아니라 코드에 대한 데이터를 명확하게 하여 가독성을 높일 수 있습니다.
3. Annotation
4. Concurrency API
API를 사용하여 병렬 프로그래밍 혹은 멀티 스레드를 손쉽게 구현할 수 있습니다.
5. Enumeration
자바 개발자들은 데이터 구조를 더 쉽게 정의하고 사용할 수 있는 열거형(Enum) 기능을 원했고 자바 5에 추가되었습니다. 이를 이용하여 클래스, 인터페이스 열거형으로, 소스 코드를 작성할 수 있습니다.
6. Auto Boxing/Unboxing
오토박싱/언박싱 기능을 통해 개발자가 기본형 데이터를 래퍼 클래스로 직접 변환하지 않아도 언어 차원에서 자동 변환이 가능하도록 보강되었습니다.
Java SE 6(2006년 12월)
기능 변화
1. 이때부터 표기가 J2SE에서 Java SE로 바뀌었습니다.
2. 가비지 컬렉터 G1(Garbage First) GC을 오직 테스트용으로만 사용하도록 추가하였습니다.
Garbage Collection
Heap 영역 내에서 unreachable object를 찾아 회수함으로써 메모리 관리 역할을 수행합니다.
Java SE 7(2011년 7월)
기능 변화
1. Diamond Operator <>
General Class 초기화 시 Type Interface를 지원하게 되었습니다.
//Java SE 7 버전 이전
List<Integer> list = new ArrayList<Integer>();
//Java SE 7 버전 이후
List<Integer> list = new ArrayList<>();
2. switch문에서 String 사용
Tyr-Catch 내에 선언된 Collection 등의 자원을 자동으로 close 처리합니다.
Java SE 8(2014년 3월)
- 오라클 인수 후 첫 번째 버전이며, 2개 버전으로 나뉩니다.(Oracle JDK, OpenJDK)
기능 변화
1. Lambda Expression
메소드를 지칭하는 명칭 없이 구현부를 선언하는 익명 메소드 생성 문법입니다. 별도의 익명 클래스를 만들어서 선언하던 방식을 람다를 통해 대폭 간소화할 수 있으며, 함수형 프로그래밍, 스트림 API 그리고 컬럭션 프레임워크의 개선 등에 영향을 주었습니다.
List<Integer> intList = new ArrayList<Integer>();
intList.add(0);
intList.add(1);
intList.add(2);
// 클래스의 static 메소드
List<List<Integer>> resultList = intList.stream().map(Arrays::asList).collect(Collectors.toList());
// 인스턴스의 메소드
List<Integer> resultList = intList.stream().map(intList::get).collect(Collectors.toList());
// 클래스의 생성자
List<Double> resultList = intList.stream().map(Double::new).collect(Collectors.toList());
System.out.println(intList);
System.out.println(resultList);
2. Method Reference
메서드 레퍼런스는 특정 메서드만을 호출하는 람다의 축약형입니다. 메서드 레퍼런스를 새로운 기능이 아니라 하나의 메서드를 참조하는 람다를 편리하게 표현할 수 있는 문법으로 간주할 수 있습니다.
람다와 메서드 레퍼런스 단축 표현 예시
람다 | 메서드 레퍼런스 |
(Soccer s) -> s.getGoal() | Soccer::getGoal |
() -> Thread.currentThread().dumpStack() | Thread.currentThread()::dumpStack |
(str, i) -> str.substring(i) | String::substring |
(String s) -> System.out.println(s) | System.out::println |
3. Interface의 Default Methods
Java SE 8에서는 인터페이스에 디폴트 메소드(Default Methods)라는 것이 추가되었습니다. 인터페이스는 메소드 정의만 할 수 있고 구현은 할 수 없었지만, Java SE 8에서부터는 디폴트 메소드라는 개념이 생겨 구현 내용도 인터페이스에 포함시킬 수 있습니다.
// 일반적인 인터페이스 구현
public interface Soccer {
public void doShooting(int n);
}
// 디폴트 메소드를 사용하여 구현 내용을 인터페이스에 포함
public interface Soccer {
public default void doShooting(int n) {
System.out.println("doShooting(Shooting)");
}
}
// 디폴트 메소드가 구현된 인터페이스 또한 상속 받을수 있음
public interface Soccer {
public default void doShooting(int n) {
System.out.println("doShooting(Shooting)");
}
}
public interface SoccerChild extends Soccer {
}
4. Null 처리 Optional 추가
이전까지 변수의 null 여부를 검사하고 대응하기 위해 많은 노력을 했습니다. Java SE 8부터는 Optional이라는 구조체를 제공해서 이전보다 간편하게 NPE(Null Pointer Exception) 이슈에 대응할 수 있습니다.
// Optional 구조체의 생성
Optional<String> optionalStr = Optional.empty();
Optional<String> optionalStr = Optional.of("str");
Optional<String> optionalStr = Optional.ofNullable("str");
// null 일 경우
System.out.println(optionalStr.orElse("empty str"));
// java8 Optional 이전까지의 null 대응
String value = null;
String result = "";
try {
result = value.toUpperCase();
} catch (NullPointerException exception) {
throw new Exception();
}
// java8 Optional 이후의 null 대응
String value = null;
Optional<String> valueOpt = Optional.ofNullable(value);
String result = valueOpt.orElseThrow(Exception::new).toUpperCase();
5. 새롭게 추가된 날짜와 시간 API
기존 Date와 Calendar 클래스의 기능 부족과 비 표준적인 명명 규칙, 그리고 일관되지 못한 속성 값의 문제를 해결하기 위해 새로운 날짜 API가 추가되었습니다.
//javax.time.Clock
Clock.systemUTC(); //current time of your system in UTC.
Clock.millis(); //time in milliseconds from 1/1/1970.
//javax.tme.ZoneId
ZoneId zone = ZoneId.of(“Europe/London”); //zoneId from a timezone.
Clock clock = Clock.system(zone); //set the zone of a Clock.
//javax.time.LocalDate
LocalDate date = LocalDate.now(); //current date
String day = date.getDayOfMonth(); //day of the month
String month = date.getMonthValue(); //month
String year = date.getYear(); //year
6. Stream API
Stream이란 순차/병렬 작업을 지원하는 어떠한 순차적인 요소입니다. 쉽게 스트림을 데이터 컬렉션 반복을 처리하는 기능입니다. 람다 표현식, 함수형 인터페이스 그리고 메서드 참조를 이용한 최종 산출물입니다. 기존 컬렉션 프레임워크를 이용할 때보다 간결하게 코드 작성이 가능합니다. 병렬처리, 스트림 파이프라인 등을 통해 하나의 문장으로 다양한 처리 기능을 구현 가능합니다.
7. PermGen Area 제거
Java8 이전에는 초기 설정 시 PermSize와 MaxPermSize를 설정해주어야 했으나, Java8부터는 Permanent Generation이 Metaspace로 대체되었습니다. Metaspace는 런타임 시 메모리 요구 사항에 따라 자체 크기를 조정하며, 필요하다면 MaxMetaspaceSize 매개변수를 설정하여 Metaspace의 양을 조절할 수 있습니다.
Permanent Generation
- Permanent Generation은 Class 혹은 Method Code가 저장되는 영역
- PermGen은 Heap 영역에 속함
- Default로 제한된 크기를 가지고 있음
Metaspace
- Metaspace는 Java 클래스 로더가 현재까지 로드한 Class들의 메타데이터가 저장되는 공간
- JVM에 의해 관리되는 Heap 영역이 아니라 OS 레벨에서 관리되는 Native 메모리 영역에 위치
- Default로 제한된 크기를 가지고 있지 않고, 필요한 만큼 늘어남
Java SE 9(2017년 9월)
기능 변화
1. 모듈시스템 jigsaw 등장
이전까지 자바에서는 name space를 사용한 패키지와 gradle, maven을 사용하여 패키지와 라이브러리를 관리하였습니다. 하지만 기존의 방법들에는 서로 다른 패키지간의 캡슐화가 지원되지 않았습니다.
jigsaw는 모듈을 만들고 모듈에 명시적으로 외부에서 호출할 수 있는 API를 선언합니다. 언어 레벨에서 API 작성자가 외부에 노출한 API 외에는 접근할 수 없습니다. 뿐만 아니라 모듈은 그 모듈에서 사용할 다른 모듈을 선언합니다. JDK는 이 기능을 통해 모든 내부 API를 캡슐화하여 구성합니다.
Jigsaw Project의 목적
- SE 플랫폼과 JDK를 작은 컴퓨터 디바이스에 보다 쉽게 경량화(scalable down) 할 수 있게 합니다.
- Java SE 플랫폼의 전반적인 구현 부분과 특히 JDK 부분의 보안성과 유지관리성(maintainability)을 향상합니다.
- 애플리케이션의 성능을 높입니다.
- Java SE 그리고 EE 플랫폼에서 개발자들이 라이브러리와 래플리케이션 구성, 유지를 쉽게 만들어 줍니다.
- Jigsaw의 주요 목표는 한마디로 유연한 런타임 이미지를 만들 수 있도록 Java 플랫폼을 모듈화 하는 것입니다.
// Java 코드 최상위에 module-info.java 파일을 만들고, 아래와 같이 사용함
module java.sql {
requires public java.logging;
requires public java.xml;
exports java.sql;
exports javax.sql;
exports javax.transaction.xa;
}
2. A New HTTP Client
Java SE 8까지 사용하던 HttpURLConnection을 대체할 새로운 java.net.http 패키지가 추가되었습니다.
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://postman-echo.com/get"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandler.asString());
3. Jshell - The Java Shell
Java SE 9은 테스트 프로젝트나 main 메소드 없이 코드를 신속하게 테스트할 수 있는 대화식 REPL(Read-Eval-Print-Loop) 도구를 제공합니다.
4. Process API 개선
OS 프로세스 관리 및 컨트롤을 위해 아래의 두 개 패키지가 추가되었습니다. 아래와 같이 사용할 수 있습니다.
java.lang.ProcessHandle
java.lang.ProcessHandle.Info
//다음과 같이 사용 가능
ProcessHandle processHandle = ProcessHandle.current();
ProcessHandle.Info = processHandle.info();
5. try-with-resources 개선
void tryWithResourcesByJava7() throws IOException {
BufferedReader reader1 = new BufferedReader(new FileReader("test.txt"));
try (BufferedReader reader2 = reader1) {
// do something
}
}
// final or effectively final이 적용되어 reader 참조를 사용할 수 있음
void tryWithResourcesByJava9() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("test.txt"));
try (reader) {
// do something
}
}
6. 다이아몬드 연산자(Diamond Operator)
Java SE 7에는 코드를 보다 읽기 쉽게 만드는데 도움 되는 다이아몬드 연산자(Diamond Operator)라는 새로운 기능이 있었지만, 익명 클래스(Anonymous Inner Class)에는 컴파일 오류가 발생하여 제한적이었습니다.
Java SE 9 이후부터는 익명 클래스에서도 사용할 수 있도록 개선되었습니다.
FooClass<Integer> fc = new FooClass<>(1) {
// anonymous inner class
};
FooClass<? extends Integer> fc0 = new FooClass<>(1) {
// anonymous inner class
};
FooClass<?> fc1 = new FooClass<>(1) {
// anonymous inner class
};
// 타입 파라메터없이 List만 사용해도 추론이 가능함
public List getPerson(String id) {
return new List(findPersonById(id)){};
}
7. Interface Private Method
인터페이스 내에서 private 메서드 사용이 가능해졌습니다.
interface NewInterface {
private static String staticPrivate() {
return "static private";
}
private String instancePrivate() {
return "instance private";
}
default void check() {
String result = staticPrivate();
NewInterface newIf = new NewInterface() {
// anonymous class
};
result = newIf.instancePrivate();
}
}}
8. Optional To Stream
Stream<Optional> person = getPerson(id);
// Optional.stream은 Stream<Optional>을 Stream<Person>으로 바꾸어줌
Stream personStream = person.flatMap(Optional::stream);
// 아래와 같이 Optional로 Stream을 생성할 수 있음.
Stream<Integer> stream = Optional.of(1).stream();
Java SE 10(2018년 3월)
기능 변화
1. Local-Variable Type Interface
로컬 변수 타입 추론 기능입니다. 로컬 변수 타입을 'var'로 선언할 수 있습니다.
다음과 같은 케이스에만 적용이 됩니다.
- initializer와 함께 선언되는 로컬 변수
- enhanced for-loop 내 index 변수
- traditional for-loop 내 로컬 변수
var list - new ArrayList<String>(); //ArrayList<String> 으로 추론
var stream = list.stream(); //Stream<String> 으로 추론
var numbers = List.of(1, 2, 3, 4, 5); //List<Integer> 으로 추론
for (var number : numbers){ //Integer 추론
System.out.println(number);
}
2. Garbage Collector Interface
다양한 GC의 코드 고립도를 향상하는 인터페이스를 도입하였습니다.
3. Thread-Local Handshakes
VM safepoint를 수행할 필요 없이 개별 스레드를 stop 시키고 콜백을 수행하도록 할 수 있는 기능을 도입하였습니다.
VM safepoint란?
"Stop The World"로 표현되며, 모든 스레드를 일시 정지시키는 작업입니다.
safepoint를 발생시키는 경우
- Garbage collection pauses
- Code deoptimization
- Flusing code cache
- Class redefinition
- Biased lock revocation
- Various debug operation
4. Root Certificates
HTTPS 통신에 쓰이는 SSL/TLS 인증서를 발급해주는 인증 기관인 CA 중에서 root CA 목록을 브라우저와 마찬가지로 Oracle JDK에서도 가지고 있습니다. OpenJDK도 이를 Java SE 10부터 지원합니다.
Java SE 11(2018년 9월)
Oracle JDK와 OpenJDK가 통합되었으며 Oracle JDK 가 유료 모델로 전환되었습니다.
기능 변화
1. HTTP 클라이언트(JEP 321)
Java SE 9에 인큐베이팅 형태로 넣었던 HTTP 클라이언트 API를 정식적으로 포함했습니다. 이 API는 기존에 제공되는 URLConnection 기반의 HTTP 개발보다 개선된 기능과 명명규칙을 제공합니다. 특히 HTTP 2.0을 지원하여 웹 소켓 기능도 포함되어있습니다.
2. 새로운 String 메서드 추가
strip() | 문자열 앞, 뒤의 공백 제거 |
stripLeading() | 문자열 앞의 공백 제거 |
stripTrailing() | 문자열 뒤의 공백 제거 |
isBlank() | 문자열이 비어있거나 공백만 포함되어있을 경우 true를 반환. 즉, String.trim().isEmpty() 호출과 같음 |
lines() | 문자열을 라인 단위로 쪼개는 스트림을 반환 |
repeat(n) | 지정된 수 만큼 문자열을 반복하여 붙여 반환 |
trim()은 U+0020 이하의 값만을 공백으로 인식하여 제거하였습니다.(tab, CR, LF, 공백) 하지만 유니코드에서는 이 외에 다양한 공백 문자가 존재하는데, 이를 처리하기 위해서는 기존엔 Chararcter.isWhitespace(int)를 사용해야만 했습니다.
Java SE 11부터는 strip()으로 편하게 처리할 수 있습니다.
//repeat(n) 예시
String str = "ABC";
String repeated = str.repeat(3); // "ABCABCABC"
3. Lambda 파라미터로 var 사용
Java SE 10에서 var 키워드로 변수를 선언하면 타입 추론으로 객체를 생성할 수 있는 기능이 추가되었습니다. Java SE 11에서는 여기에 람다 표현식에서도 var를 사용해서 변수를 선언할 수 있게 되었습니다.
(var x, var y) -> x.process(y) => (x, y) -> x.process(y)
Java SE 12(2019년 3월)
기능 변화
1. 문법적으로 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;
}
//Java SE 12 부터의 방식
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);
}
2. 가비지 컬렉터 개선, 마이크로 벤치마크 툴 추가, 성능 개선의 변경점이 있습니다.
Java SE 13(2019년 9월)
기능 변화
1. switch문 개선을 위한 yield라는 예약어 추가
var a = switch (day) {
case MONDAY, FRIDAY, SUNDAY:
yield 6;
case TUESDAY:
yield 7;
case THURSDAY, SATURDAY:
yield 8;
case WEDNESDAY:
yield 9;
};
2. Text Block
줄 바꿈 문자가 자동으로 포함됩니다.
String str = """
This
is
text block
""";
Java SE 14(2020년 3월)
기능 변화
1. 스위치 표현(Standard)
Java SE 12 및 13에서 preview였던 스위치 표현식이 이제 표준화되었습니다.
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
default -> {
String s = day.toString();
int result = s.length();
yield result;
}
};
2. record(preview)
Java로 많은 상용구를 작성하는 고통을 완화하는데 도움이 되는 레코드 클래스가 있습니다.
데이터, getter/setter, equals/hashcode, toString만 포함되는 이 Java SE 14 이전 클래스
final class Point {
public final int x;
public final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
*// state-based implementations of equals, hashCode, toString// nothing else*
레코드 사용
record Point(int x, int y) { }
3. 유용한 NullPointerExceptions
NullPointerExceptions은 정확히 어떤 변수가 null인지 설명합니다.
author.age = 35;
---
Exception in thread *"main"* java.lang.NullPointerException:
Cannot assign field *"age"* because *"author"* is null
Java SE 15(2020년 9월)
기능 변화
1. Text-Blocks / Multiline Strings
Java SE 13의 실험 기능으로 도입된 여러 줄 문자열은 이제 프로덕션 준비 완료되었습니다.
String text = *"""
Lorem ipsum dolor sit amet, consectetur adipiscing \
elit, sed do eiusmod tempor incididunt ut labore \
et dolore magna aliqua.\
"""*;
2. Sealed Classes - Preview
상속 가능한 클래스를 지정할 수 있는 봉인 클래스가 제공됩니다. 상속 가능한 대상은 상위 클래스 또는 인터페이스 패키지 내에 속해 있어야 합니다.
public abstract sealed class Shape
permits Circle, Rectangle, Square {...}
즉, 클래스가 public인 동안 하위 클래스로 허용되는 유일한 Shape 클래스들은 Circle, Rectangle 및 Square입니다.
Java SE 16(2021년 3월)
기능 변화
1. OpenJDK의 버전 관리 : Git
OpenJDK 의 버전 관리가 Mercurial이었으나, Git으로 바뀌었습니다. 이제 OpenJDK 소스를 GitHub에서 볼 수 있습니다.
2. Unix-Domain Socket Channels
이제 Unix 도메인 소켓에 연결할 수 있습니다.(macOS 및 Windows(10+)에서도 지원)
socket.connect(UnixDomainSocketAddress.of(
*"/var/run/postgresql/.s.PGSQL.5432"*));
Java SE 17(2021년 9월)
기능 변화
1. RandomGenerator(의사난수 생성기)
의사난수 생성기를 통해 예측하기 어려운 난수를 생성하는 API가 정식 출시되었습니다.
참고 출처
https://www.marcobehler.com/guides/a-guide-to-java-versions-and-features
https://velog.io/@ljo_0920/java-%EB%B2%84%EC%A0%84%EB%B3%84-%EC%B0%A8%EC%9D%B4-%ED%8A%B9%EC%A7%95
https://hajoung56.tistory.com/35
'Programming > Java' 카테고리의 다른 글
Java 기초 상식 정리 (0) | 2023.04.23 |
---|---|
JSON 파싱 2020. 06 .24 (0) | 2020.06.29 |
국립국어원_HTTP적용 2020. 06 .24 (0) | 2020.06.29 |
HttpClient 또오해영 (0) | 2020.06.29 |
우리말샘 API 2020. 06 .24 (0) | 2020.06.29 |