[Java] Version과 Version별 Feature
오늘은 Java 버전에 관하여 얘기해보자.
1.x와 x의 차이?
먼저 얘기하고 싶은 건 1.8과 8과 같이 1.x로 부르는 것과 x로만 부르는 버전의 차이다.
결론만 말하자면 1.8과 8은 같은 버전이며, 1.x를 x로도 부른다.
1.x.x 로 칭하는 것은 JDK, 즉 Java Development Kit 개발자들끼리 흔히 Version String으로 부르는 것이고,
x로 칭하는 것들은 Java SE, 즉 Java Standard Edition으로 일반적으로 칭하는 Version Number를 사용한 것이라 한다.
이는 초기에 Sun Microsystem이 Java를 개발하던 시기에는 1.x로 사용되다가 이후 Oracle Corpotation이 Sun 사를 인수 하면서 릴리즈한 것은 Java 7이었으며 이후로 네이밍 규칙을 바꿨다.
웬만하면 x의 Version Nnumber로 부르라 하니 그렇게 하자.
OracleJDK, Open JDK
Closed Source, Open Source의 차이.
흔히유료냐 무료냐를 나누는 기준이 된다.
OpenJDK는 Oracle, Red Hat과 같은 기업은 물론 커뮤니티에서도 관리하는 오픈소스 프로젝트지만,
Oracle JDK는 Closed Source로 유료 라이센스가 필요하며, 관리의 주체가 Oracle이라는 것이다.
Java 11부터는 이 둘의 차이가 크게 없는 것으로 여겨진다.
Oracle JDK를 사용한다면 아무래도 돈을 내다보니 안정성, 성능 및 문제점 분석, 모니터링 및 관리 등 OpenJDK 보다 지원과 안정성 확보에 장점은 있겠다.
하지만 업데이트 주기가 느리다 보니 마이그레이션 시점에서 지원하지 않는 기능이 있을 수 있기에 잘 고려해서 사용해야 한다.
JRE와 JDK의 차이
JRE는 Java Runtime Environment의 약자로 단순히 Java 기반의 프로그램을 구동하는 데 필요한 환경을 구성해 준다.
JDK는 Java Development Kit의 약자로 JRE는 물론이고 컴파일러인 javac와 Java documentation 생성기 javadoc, 디버거인 JDB 등을 포함하여 Java로 개발하는 데 필요한 패키지라 볼 수 있다.
Java 9버전에서부터는 JDK, JRE 분리 없이 전체 기능을 제공하는 경향으로 바뀌었다.
회사에서 흔히 Java 8을 사용하는 이유
일단 Java 8은 2014년 3월 18일에 릴리즈 되었다.
꽤 오래된 버전인데 왜 아직도 사용하는 걸까.
1. LTS 버전.
LTS는 Long-Term Support 의 약자로써 말 그대로 오랜 기간 동안 지원을 해준다는 거다.
현재까지 지원 중인 LTS 버전과 지원 기간을 간단히 설명하자면
- 8 - 2030년 12월
- 11 - 2026년 9월
- 17 - 2029년 9월
와 같고 8이 제일 길게 지원한다.
2. Maven, Gradle와 라이브러리 호환
일부 라이브러리와 Maven, Gradle과 같은 빌드 도구와 완벽한 호환이 되지 않아 Java 프로젝트 빌드가 정상적으로 이루어졌음에도 “reflective access” 경고가 떴었다.
그렇다고 한다.
필자는 전 회사에서 7버전을 사용했었다. 하하.
버전별 차이와 기능
일단 자바는 역호환이라는 Backwards compatible의 특징이 있는데 이는 몇 가지를 제외하고는 Java 5, 8도 Java 8-20의 JVM 환경에서 구동된다는 것을 의미한다.
이는 특정 Java 버전을 학습하기보단 Java의 기능 자체를 학습한다는 의미를 가진다고 해석할 수 있을 것 같다.
버전은 8~20의 주요 기능들을 간단한게 돌아볼 것이다.
Java 8
1. Lambda
8이전에는 인스턴스화 하기 위해서는 익명 함수를 사용하는 방법밖에 없었지만 이를 더욱 간결하게 표현할 수 있는 람다식이 추가 되었다.
[Java 8 이전]
Runnable runnable = new Runnable(){
@Override
public void run(){
System.out.println("Hello world !");
}
};
[Java 8 이후]
Runnable runnable = () -> System.out.println("Hello world two!");
둘 다 동일한 동작을 수행하기 위한 지시다.
2. Collections & Streams
8부터 함수형 프로그래밍을 본격적으로 차용했다 할 수 있다.
List와 같은 Collections 자료 구조를 생성하는 메서드 추가와 Collection 처리를 간결하고 효율적으로 Stream API써서 표현할 수 있게 되었다.
List<String> list = Arrays.asList("franz", "ferdinand", "fiel", "vom", "pferd");
list.stream()
.filter(name -> name.startsWith("f"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
이외에도 interface default method, Optional, Date/Time 표현 API 가 추가 되었다.
Java 9
1. Collections
Collections의 자료 구조를 좀 더 쉽게 다룰 수 있는 메서드가 추가되었다.
List<String> list = List.of("one", "two", "three");
Set<String> set = Set.of("one", "two", "three");
Map<String, String> map = Map.of("foo", "one", "bar", "two");
2. Stream
takeWile, dropWhile, iterate 등과 같은 메서드가 추가 되었다.
Stream<String> stream = Stream.iterate("", s -> s + "s")
.takeWhile(s -> s.length() < 10);
3. Optionals
Optionals에서 사용할 수 있는 ifPresentOrElse 메서드 추가
user.ifPresentOrElse(this::displayAccount, this::displayLogin);
4. Intefaces
Interfaces에 private methods가 추가되었다.
public interface MyInterface {
private static void myPrivateMethod(){
System.out.println("Yay, I am private!");
}
}
5. JShell
Java에서 Shell의 실행과 결과를 출력할 수 있게되었다.
% jshell
| Welcome to JShell -- Version 9
| For an introduction type: /help intro
jshell> int x = 10
x ==> 10
6. HTTPClient
기존에 있던 Http 지원은 low-level이기에 이를 지원하는 Apache HttpClient, OKHttp등과 같은 라이브러리에 의존했었지만 이를 개선할 HttpClient의 프리뷰 버전을 추가했다.
이외에도 Java 버전에 따라 동작을 다르게 할 수 있는 Multi-Release jar를 지원하는 Project Jigsaw로 런타임 모듈화를 도입, try-with-resources 구문 추가와 다이아몬드 연산자의 기능 확장이 있었다.
Java 10
1. var
지역 변수 타입 추론(local-variable type inference)을 수행할 수 있는 var 키워드가 추가되었다.
// Pre-Java 10
String myName = "Marco";
// With Java 10
var myName = "Marco"
이외에도 Garbage Collection 의 변경 등이 있었다.
Java 11
1. Strings & Files
String과 File에 새로운 메서드들이 추가되었다.
"Marco".isBlank();
"Mar\nco".lines();
"Marco ".strip();
Path path = Files.writeString(Files.createTempFile("helloworld", ".txt"), "Hi, my name is!");
String s = Files.readString(path);
2. Run Source Files
Java 10에서부터 시작되었으며, .java와 같은 확장자를 가진 Java Source 파일을 컴파일하지 않고 실행할 수 있게 되었다.
ubuntu@DESKTOP-168M0IF:~$ java MyScript.java
3. var for lambda parameters
Lambda 파라미터로 var를 사용할 수 있게 됐다.
(var firstName, var lastName) -> firstName + lastName
4. HttpClient
Java 9에서 언급한 HttpClient의 프리뷰 버전이 더 이상 프리뷰가 아닌 정식으로 추가되었다.
이외에도 Flight Recorder, No-Op Garbage Collector, Nashorn-Javascript-Engine deprecated 등이 있었다.
Java 12
1. Unicode 11 지원
Java 13
1. Switch Expression (preview)
Switch 표션식에서 값을 return 받을 수 있게되었고, fall-through/break 이슈 없이 Lambda 스타일로 표현할 수 있게 되었다.
이전 switch는
switch(status) {
case SUBSCRIBER:
// code block
break;
case FREE_TRIAL:
// code block
break;
default:
// code block
}
와 같았고 13 이후에는 아래와 같이 표현할 수 있게 되었다.
boolean result = switch (status) {
case SUBSCRIBER -> true;
case FREE_TRIAL -> false;
default -> throw new IllegalArgumentException("something is murky!");
};
2. Multiline Strings (preview)
String 변수 선언 시 한 줄이 아닌 여러 줄을 +
를 이용하여 값을 선언할 수 있게 되었다.
String htmlBeforeJava13 = "<html>\n" +
" <body>\n" +
" <p>Hello, world</p>\n" +
" </body>\n" +
"</html>\n";
String htmlWithJava13 = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
이외에도 유니코드 12.1 지원, FileSystems 메서드 추가, TLS의 1.0, 1.3을 X25519, X448의 그룹으로 사용가능하게 추가 하는 등 변경이 이루어졌다.
Java 14
1. Switch Expression(Standard)
이전에 Preview였던 Switch 표현이 정식으로 개승되었다.
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
default -> {
String s = day.toString();
int result = s.length();
yield result;
}
};
2. Records (Preview)
boilerplate 코드를 작성하는데 불편함을 줄이기 위해 recoed class가 등장했다.
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
의 클래스를 지정하여 Getters/Setters, equals/hashcode, toString등을 implmentations 해서 구현했지만 record를 사용한다면
record Point(int x, int y) { }
와 같이 간결하게 표현할 수 있게되었다.
3. Helpful NullPointerExceptions
NullPointerExceptions이 발생한 변수 사용자가 알 수 있게 개선하였다.
author.age = 35;
---
Exception in thread "main" java.lang.NullPointerException:
Cannot assign field "age" because "author" is null
4. Pattern Matching For InstanceOf (Preview)
이전에는 instanceof를 검사하는 if 문 안에서 해당 Object를 (cast) 해서 변환해야됐지만 14버전에서부터는 자동으로 형 변환되어 바로 사용할 수 있게 되었다.
[14 이전]
if (obj instanceof String) {
String s = (String) obj;
// use s
}
[14 이후]
if (obj instanceof String s) {
System.out.println(s.contains("hello"));
}
5. Packaging Tool (Incubator)
Java Application을 구동되는 플랫폼에 맞게 패키징하는 jpackage tool이 추가되었다.
- Linux: deb and rpm
- macOS: pkg and dmg
- Windows: msi and exe
6. Garbage Collectors
CMS라 불리우던 Concurrent Mark Sweep Garbage Collector 가 사라지고 실험 명목으로 Z Garbage Collector가 추가되었다.
Java 15
1. Text-Blocks / Multiline Strings
13버전에서 추가되었던 Multiline String을 보완할 Text-Blocks 기능이 추가되었다.
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 {...}
sealed 된 Shape class는 서브클래스로 Circle, Rectangle, Square 를 둘 수 있다.
3. Nashorn JavaScript Engine
11버전에서부터 deprecated 된 Nashorn JavaScript Engine이 삭제되었다.
4. ZGC: Production Ready
14버전에서 실험 명목으로 추가한 Z Garbage Collector가 정식으로 채택되었다.
Java 16
1. Pattern Matching for instanceof
14버전에서 Preview로 제공되던 기능을 정식으로 사용할 수 있게 됐다.
2. Unix-Domain Socket Channels
Unix 도메인 소켓에 연결할 수 있다.(macOS, Windows에서도 지원.)
socket.connect(UnixDomainSocketAddress.of(
"/var/run/postgresql/.s.PGSQL.5432"));
3. Foreign Linker API - Preview
JNI (Java Native Interface)를 대체하기 위해 Think C 등을 통해 native 라이브러리를 bind할 수 있게 허용했다.
4. Records & Pattern Matching
preview로 제공되던 기능들이 정식으로 추가되었다.
Java 17
1. Pattern Matching for switch (Preview)
Switch에 Object를 전달할 수 있고 전달 받은 Object의 instance 별로 동작을 지정할 수 있게됐다.
public String test(Object obj) {
return switch(obj) {
case Integer i -> "An integer";
case String s -> "A string";
case Cat c -> "A Cat";
default -> "I don't know what it is";
};
}
2. Sealed Classes (Finalized)
preview 버전의 최종 버전을 배포하였다.
3. Foreign Function & Memory API (Incubator)
JNI 대체를 위해 JVM 메모리 외부 영역에서 Native functions을 가져와 사용할 수 있게 허용했었다.
Think C의 언어만 지원했지만 점차 많은 언어를 지원할 예정.
4. Deprecating the Security Manager
이후 버전에서 부터 Java 1.0 부터 있던 Security Manager를 deprecated하고 remove할 예정이다.
Java 18
1. UTF-8 by Default
사용자의 설정 없이는 OS 에 따라 인코딩이 마다 달랐지만, 18버전에서부터는 기본적으로 UTF-8로 인코딩을 수행한다.
2. Simple Web Server
jwebserver
의 간단한 명령어만으로 기초 HTTP 서버를 실행할 수 있다.
Java 19
Virtual Threads, Structured Concurrency 와 Vector API로 알려진 Foreign Function 와 Memory API의 새로운 버전 제공.
Java 20
Scope Values, Record Patterns, switch에서의 Pattern Matching , Foreign Function & Memory API, Virtual Threads & Structured Concurrency 등 이전에 정식으로 공개되지 않은 기능들을 preview로 계속해서 제공한다.
Ref.
https://goateedev.tistory.com/210
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