public interface MyInterface {
// public 추상 메서드
void publicMethod();
// Java 11부터 추가된 private 메서드
private void privateMethod() {
// private 메서드의 구현
System.out.println("This is a private method.");
}
// public 메서드에서 private 메서드 호출
default void callPrivateMethod() {
privateMethod();
}
}
Java11부터 OracleJDK가 유료화 되었다.
그에 따라 무료인 OpenJDK의 중요성이 올라갔다.
따라서 Oracle은 OracleJDK와 OpenJDK를 통합하기로 했다.
Java11부터 LTS(Long-Term Support)와 비LTS 구분
분산된 가비지 컬렉터 : 전체 힙을 일정 크기 영역으로 나누고 각 영역에서 가장 많은 가비지를 가진 영역을 우선 수집
힙 크기 제한 : 미리 최대 힙 크기를 설정하여 메모리 사용량을 미리 제한
영역별 가비지 컬렉션 제어 : 영역별로 제어가 가능하기에 응답 시간의 향상을 이끌어낸다.
적절한 힙 크기 및 다른 JVM 옵션을 설정해야 한다.
원하는 성능에 따라 튜닝과 모니터링이 필요할 수 있다.
// Java 8 이전의 익명 내부 클래스를 사용한 예제
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Hello, World!");
}
};
// Java 8에서의 람다 표현식
Runnable runnable = () -> {
System.out.println("Hello, World!");
};
var 키워드가 도입되었다.// Java 10 이후의 var 키워드 사용
var name = "John"; // String으로 유추
var age = 30; // int로 유추
// Java 11에서의 람다와 var의 조합
(var x, var y) -> {
var result = x + y; // result 변수의 타입은 컴파일러가 유추
System.out.println(result);
};
// Java 9의 불변 리스트 생성
List<String> list = List.of("A", "B", "C");
// Java 11에서 더 많은 요소를 포함하는 불변 리스트 생성
List<String> list = List.of("A", "B", "C", "D", "E");
Key-Value 형태를 이용하여 불변 Map 생성
이전에는 Key, Value를 직접 나열해야 했지만 Map.ofEntries()를 활용하여 편리한 불변 맵 생성 가능
// Java 11에서 불변 맵 생성
Map<String, Integer> map = Map.ofEntries(
entry("A", 1),
entry("B", 2),
entry("C", 3)
);
// 불변 리스트 생성
List<String> list = Stream.of("A", "B", "C")
.collect(Collectors.toUnmodifiableList());
// 불변 집합 생성
Set<Integer> set = Stream.of(1, 2, 3)
.collect(Collectors.toUnmodifiableSet());
String text = "Hello\nWorld\nJava\n11";
// 문자열을 줄 단위로 분할
List<String> lines = text.lines()
.collect(Collectors.toList());
// 결과: ["Hello", "World", "Java", "11"]
String text = "Hello\nWorld\nJava\n11";
// 문자열을 줄 단위로 분할
List<String> lines = text.lines()
.collect(Collectors.toList());
// 결과: ["Hello", "World", "Java", "11"]
기존 : final을 사용하여 선언한 변수는 재할당 금지 -> 불변성 보장
Java 11 : var 변수 또한 초기화 이후 재할당 금지 -> 불변성 보장
var x = 10; // 초기화
x = 20; // 컴파일 오류! 재할당 불가능
record 클래스 키워드 : 클래스를 간결하게 정의하고 데이터 객체를 생성하는데 사용불변성(Immutability) : record 클래스 필드는 기본적으로 final으로 선언되어 불변성을 보장
필드 정의(Field Definitions) : 필드를 간결하게 정의한다.
private final로 간주Getter 메서드(Accessor Methods) : 자동 생성된 getter 메서드 제공
equals(), hashCode(), toString() 메서드 자동 생성
생성자(Constructor) 자동 생성
명시적 메서드 추가 가능 : 필요하다면 record 클래스에 추가 메서드 정의 가능
record Person(String name, int age) {
// 다른 메서드를 추가할 수 있음
}
// Usage
Person person = new Person("Alice", 30);
System.out.println(person.name()); // "Alice"
System.out.println(person.age()); // 30
java.util.random 패키지에 추가java.util.Random 클래스보다 더 강력하고 예측 가능성 낮은 난수를 생성하기 위한 새로운 방법을 제공새로운 난수 생성기 : RandomGenerator 인터페이스를 도입 -> SplittableRandom, Xoshiro256PlusPlus, L64Xoshiro256PlusPlus, L64Xoshiro512PlusPlus 등 여러 구현체 포함
SplittableRandom 클래스
SplittableRandom random = new SplittableRandom();
int randomNumber = random.nextInt(1, 100); // 1부터 99까지의 난수 생성
추가 기능
split() 메서드를 활용하여 어러 독립적인 난수 생성기 생성 가능nextBytes() 메서드를 사용하여 바이트 배열에 난수를 채울 수 있다.무결성과 예측 불가능성
java.security.SecureRandom과 비슷한 용도java.util.Random)보다 java.util.random 패키지는 더 강력하고 안전한 난수 생성을 제공한다.클래스와 인터페이스를 제한된 하위 클래스 집합으로 제어하고 캡슐화를 강화하는 기능 제공
특정 클래스를 확장하거나 인터페이스를 구현하는 클래스를 제한하고 런타임 시에 클래스 계층 구조를 더 안정적으로 만들 수 있다.
sealed : 봉인 클래스 정의 시 클래스 선언 앞에 붙임
permits 키워드 : 허용되는 하위 클래스 명시
sealed class Shape permits Circle, Rectangle, Triangle {
// 클래스 멤버 정의
}
제한된 상속: sealed 클래스의 하위 클래스는 명시적으로 허용된 클래스
열거 형식과의 결합 : 특정 상수 집합만 허용되는 경우 유용하게 사용
sealed interface TrafficSignal permits RedSignal, GreenSignal, YellowSignal {
void display();
}
enum RedSignal implements TrafficSignal {
RED {
@Override
public void display() {
System.out.println("Red Signal");
}
}
}
enum GreenSignal implements TrafficSignal {
GREEN {
@Override
public void display() {
System.out.println("Green Signal");
}
}
}
enum YellowSignal implements TrafficSignal {
YELLOW {
@Override
public void display() {
System.out.println("Yellow Signal");
}
}
}
유연한 설계 : 클래스 계층 구조를 더욱 유연하게 설계 가능
API 설계에 활용
텍스트 블록(Text Block) : 여러 줄로 이루어진 문자열 리터럴을 더욱 쉽게 작성 가능
텍스트 블록 : " 세개로 시작하고 끝, 그 사이에 여러 줄의 텍스트 입력 가능
String textBlock = """
This is a
text block
in Java 17.
""";
String name = "Alice";
String textBlock = """
Hello, ${name}!
Welcome to Java 17.
""";
SQL 쿼리, HTML 또는 JSON 템플릿, 메시지 리소스 파일, 소스 코드 생성 등 다중 줄 텍스트를 다루어야 할 때 유용하게 사용
코드의 가독성을 높이고 유지보수를 더욱 쉽게 만듦
NumberFormat 클래스, DateTimeFormatter 기능 향상NumberFormat 클래스 기능 향상
compact 스타일 : NumberFormat.Style.COMPACT : 대규모 숫자를 간략하게 표현하는데 유용 ex> "1K", "1M"NumberFormat compactFormat = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
String formatted = compactFormat.format(1000);
System.out.println(formatted); // 출력: "1K"
DateTimeFormatter 클래스 기능 향상
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.US);
String formattedDateTime = LocalDateTime.now().format(customFormatter);
System.out.println(formattedDateTime);
새로운 메서드와 유틸리티
DateTimeFormatter.parseBest() 메서드를 사용하여 여러 형식의 입력을 파싱할 수 있다.DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
TemporalAccessor temporal = DateTimeFormatter.parseBest("2023-09-17", LocalDate::from, YearMonth::from);
Stream.toList() : Stream 요소를 List로 손쉽게 변환import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
Stream<String> stringStream = Stream.of("A", "B", "C");
List<String> stringList = stringStream.toList();
System.out.println(stringList); // 출력: [A, B, C]
}
}
NullPointerException이 발생한 위치와 관련 정보를 더욱 자세히 제공한다.NullPointerException.getMessage() : 변수 이름과 null 값을 포함한 더욱 자세한 정보를 반환Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "str" is null
NullPointerException.printStackTrace() : 어떤 변수에서 null이 발생했는지 포함실시간(Low-Latency) GC : 메모리 관리 수행 동안 일시 중지 시간을 최소화하려고 노력
대규모 메모리 지원 : 매우 큰 힙 크기에서도 효율적으로 작동 -> 대규모 데이터 처리 및 메모리 집약적 애플리케이션에 적합
안정적 성능 : 예측 가능하고 더욱 안정적인 성능 제공
구성 가능한 일시 중지 시간 : 개발자가 직접 일시 중지 시간 목표 설정 가능 -> GC의 Trade-Off 조정
멀티 스레드 환경 지원 : 동시성 및 병렬 처리를 최대한 활용하여 GC 수행
안전성 및 신뢰성 : 다양한 안전 메커니즘 내재
100% Java 기반 : JVM 밖에서 별도의 Native 라이브러리를 필요로 하지 않음
로컬 변수 유형 추론의 개선:
자바 11에서는 'var' 키워드를 사용하여 로컬 변수의 유형을 추론할 수 있게 되었다.
자바 17에서는 로컬 변수 유형 추론이 더 개선되었으며, 람다식과 익명 클래스에서도 'var'를 사용할 수 있게 되었다.
새로운 기능과 개선된 API:
자바 17에서는 다양한 새로운 기능과 API 개선이 이루어졌다.
예를 들어, 'Sealed Classes'가 도입되어 클래스의 상속을 제한하고, 'Pattern Matching for switch'가 확장되어 패턴 매칭 기능이 향상되었다.
Garbage Collector 개선:
자바 17에서는 'Z Garbage Collector'의 개선과 함께 새로운 'Shenandoah Garbage Collector'가 추가되었다.
이러한 변경으로 GC 성능과 응답 시간이 개선되었다.
암호화화 관련 업데이트:
자바 17에서는 암호화와 보안 관련 업데이트가 이루어졌다.
암호화 알고리즘과 보안 기능의 업데이트로 애플리케이션의 보안성이 향상되었다.
언어 및 컴파일러 개선:
자바 17에서는 언어 및 컴파일러 개선이 이루어져 더 나은 코드 작성이 가능해졌다.
예를 들어, 'sealed', 'record', 'permits' 등의 키워드를 사용하여 코드를 더 명확하고 안전하게 작성할 수 있다.
Deprecation과 Removal:
자바 17에서는 일부 구식된 기능들이 표시되어 Deprecated 상태로 변경되거나, 더 이상 사용되지 않는 기능들이 제거되었다.
성능 개선:
자바 17은 전반적으로 성능 개선이 이루어져 더 빠르고 효율적인 실행이 가능해졌다.
다양한 다른 업데이트:
자바 17은 모듈 시스템, 컨테이너 지원, 런타임 성능 분석 등 여러 가지 다양한 개선 사항들을 포함하고 있다.
레거시 코드와의 호환성:
기존에 자바 11을 사용하던 프로젝트나 레거시 코드와의 호환성을 유지해야 하는 경우 자바 17로 업그레이드 하는 것에 어려움을 초래
프로젝트 특성과 요구사항:
특정 라이브러리나 프레임워크가 자바 11을 기반으로 개발되었거나, 특정 기능을 지원하는 경우에는 자바 11을 사용하는 것이 유리할 수 있다.
개발자 스킬과 경험:
프로젝트 팀의 개발자들이 자바 1에 더 익숙하고 경험이 있을 경우 자바 11을 선택하는 것이 더 효율적일 수 있다.
이전 버전과의 호환성 유지:
자바 11은 이전 버전과의 호환성 유지를 하는 데 도움이 될 수 있다.
업그레이드에는 더 많은 작업이 필요할 수 있다.
기업의 기존 프로젝트에는 Java 8을 사용하는 경우가 많다.
최신 IDE, 프레임워크 및 빌드 도구를 활용한 프로젝트를 시작하는 경우, 망설임 없이 Java 11(LTS), Java 17(LTS)를 사용할 수 있다.
안드로이드 개발의 경우 여전히 Java 7, Java 8 기반이 주류.
Python은 2와 3 릴리스 사이에 심각한 문제가 있다.
하위 호환성(backward compatible) : Java 5 또는 Java 8 프로그램이 Java 8 - 17 가상 머신에서 실행되도록 보장한다.
Java 8에 대한 내용들로 우선 토대를 쌓고, 11, 17 등으로 추가 기능을 학습하자.
| 특징 | OracleJDK | OpenJDK |
|---|---|---|
| 가격 | 상용(유료) | 오픈소스 기반(무료) |
| 라이선스 | Oracle BCL (Binary Code License) | Oracle GPL v2 |
| 업데이트 정책 | LTS(장기 지원) 업데이트 지원 받음 | LTS 없이 6개월마다 새 버전 배포 |
| 플러그인 | Sun Microsystems 플러그인 지원 | 지원 X |
| 성능 | 상대적으로 CPU 사용량 작음, 메모리 사용량 작음, 응답시간 높음 | 상대적으로 CPU 사용량 높음, 메모리 사용량 높음, 응답시간 낮음 |