# 자바 버전별 차이

# Java 8

# Lambda

  • 람다 표현식(lambda expression)이란 간단히 말해 메소드를 하나의 식으로 표현한 것입니다.
  • 식별자 없이 실행할 수 있는 함수 표현식을 의미하며, 따라서 익명 함수(anonymous function)라고도 부릅니다.
  • 메소드를 람다 표현식으로 표현하면 클래스를 만들고 객체를 생성하지 않아도 메소드를 사용할 수 있습니다.
  • 람다 표현식은 메소드의 매개변수로 전달될 수도 있고, 메소드의 결괏값으로 반환될 수도 있습니다.
  • 람다 표현식은 기존의 불필요한 코드를 줄여주고, 작성된 코드의 가독성을 높이는 데 그 목적이 있습니다.







 

Runnable runnable = new Runnable(){
   @Override
   public void run(){
     System.out.println(*"Hello world !"*);
   }
};
 
Runnable runnable = () -> System.out.println("Hello world!");

# Stream

  • 자바에서는 많은 양의 데이터를 저장하기 위해서 배열이나 컬렉션을 사용합니다.
    • 이때, 저장된 데이터에 접근하기 위해서는 반복문이나 반복자(iterator)를 사용하여 매번 코드를 작성해야 합니다.
    • 그러나 해당 코드는 길이가 너무 길고 가독성도 떨어지며, 코드의 재사용이 거의 불가능합니다.
  • 이 문제점을 극복하기 위해서 Java SE 8 버전부터 도입된 방법이 바로 스트림(stream) API입니다.
  • 스트림 API는 데이터를 추상화하여 다루므로, 다양한 방식으로 저장된 데이터를 읽고 쓰기 위한 공통된 방법을 제공합니다.
  • 따라서 스트림 API를 이용하면 배열이나 컬렉션뿐만 아니라 파일에 저장된 데이터도 모두 같은 방법으로 다룰 수 있습니다.
List<String> list = Arrays.asList("aa", "bb", "cc", "dd", "ee");
list.stream()
    .filter(name -> name.startsWith("a"))
    .map(String::toUpperCase)
    .sorted()
    .forEach(System.out::println);

# interface default method

  • interface 클래스에 구현 메서드를 작성할 수 있게 되었습니다.
  • 인터페이스 클래스 내부에 dafault와 static 키워드를 사용하면 구현 메서드를 작성 할 수 있습니다.

# default메소드

  • 인터페이스가 default키워드로 선언되면 메소드가 구현될 수 있다. 또한 이를 구현하는 클래스는 default메소드를 오버라이딩 할 수 있다.



 




public interface Calculator {
    public int plus(int i, int j);
    public int multiple(int i, int j);
    default int exec(int i, int j){
        return i + j;
    }
}
  • 인터페이스가 변경이 되면, 인터페이스를 구현하는 모든 클래스들이 해당 메소드를 구현해야 하는 문제가 있습니다.
  • 이런 문제를 해결하기 위하여 인터페이스에 메소드를 구현해 놓을 수 있도록 했습니다.

# static메소드







 




public interface Calculator {
    public int plus(int i, int j);
    public int multiple(int i, int j);
    default int exec(int i, int j){
        return i + j;
    }
    public static int exec2(int i, int j){   //static 메소드 
        return i * j;
    }
}
  • 인터페이스에 static 메소드를 선언함으로써, 인터페이스를 이용하여 간단한 기능을 가지는 유틸리티성 인터페이스를 만들 수 있게 되었습니다.

# Optional

  • 자바에서는 null을 다루는 것이 까다롭고, NPE가 많이 발생합니다.
  • 그래서 대부분의 코드에 null 체크 로직이 포함됩니다.
  • 자바 8 버전 이후부터는 null 체크를 깔끔하게 하는 Optional 클래스를 사용할 수 있게 되었습니다.

# java.time

  • JDK 1.0에서는 Date 클래스를 사용하여 날짜에 관한 처리를 수행했습니다.
  • 하지만 Date 클래스는 현재 대부분의 메소드가 사용을 권장하지 않고(deprecated) 있습니다.
  • JDK 1.1부터 새롭게 제공된 Calendar 클래스는 날짜와 시간에 대한 정보를 얻을 수는 있지만, 다음과 같은 문제점을 가지고 있습니다.
  1. Calendar 인스턴스는 불변 객체(immutable object)가 아니라서 값이 수정될 수 있습니다.
  2. 윤초(leap second)와 같은 특별한 상황을 고려하지 않습니다.
  3. Calendar 클래스에서는 월(month)을 나타낼 때 1월부터 12월을 0부터 11까지로 표현해야 하는 불편함이 있습니다.
  • 따라서 많은 자바 개발자들은 Calendar 클래스뿐만 아니라 더 나은 성능의 Joda-Time이라는 라이브러리를 함께 사용해 왔습니다.
  • Java SE 8 버전에서는 이러한 Joda-Time 라이브러리를 발전시킨 새로운 날짜와 시간 API인 java.time 패키지를 제공합니다.
  • java.time 패키지는 위와 같은 문제점을 모두 해결했으며, 다양한 기능을 지원하는 다수의 하위 패키지를 포함하고 있습니다.
LocalDate today = LocalDate.now();
System.out.println("올해는 " + today.getYear() + "년입니다.");

LocalDate otherDay = today.withYear(1982);
System.out.println("올해는 " + otherDay.getYear() + "년입니다.");

# Java 9

# 컬렉션

  • 컬렉션에 배열을 쉽게 생성할 수 있느 메서드가 추가되었습니다.
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");

# Java 10

  • var 키워드
  • 병렬 처리 가비지 컬렉션 도입으로 인한 성능 향상
  • JVM 힙 영역을 시스템 메모리가 아닌 다른 종류의 메모리에도 할당 가능

# 지역 변수 유형 추론: var-keyword

// Pre-Java 10
String myName = "Marco";

// With Java 10
var myName = "Marco"
  • JAVA에서 var 예약어를 사용하면 중복을 줄임으로써 코드를 간결하게 만들 수 있습니다.
    • var 키워드는 지역 변수 타입 추론을 허용합니다.
    • 메서드 내부의 변수에만 적용 가능합니다.

# Java 11

  • Oracle JDK와 OpenJDK 통합
  • Oracle JDK가 구독형 유료 모델로 전환
  • 서드파티 JDK 로의 이전 필요
  • lambda 지역변수 사용법 변경
  • 기타 추가

# Run Source Files

  • Java 소스 파일 을 먼저 컴파일 하지 않고도 실행할 수 있습니다.
  • java 명령을 사용하여 파일을 직접 실행할 수 있습니다.
$ java HelloWorld.java
Hello World

# 람다 매개변수에 대한 지역 변수 유형 추론(var)

  • 람다 표현식에서 타입 추론(var)을 사용할 수 있게 되었습니다.
// before java 11
Consumer<String> test = s -> System.out.println(s);

// after java 11
Consumer<String> test = (var s) -> System.out.println(s);

# String, Files 클래스

  • Strings and Files에는 몇 가지 새로운 메서드 추가
"Marco".isBlank();
"Mar\nco".lines();
"Marco  ".strip();

Path path = Files.writeString(Files.createTempFile("helloworld", ".txt"), "Hi, my name is!");
String s = Files.readString(path);

# Java 12

  • 유니코드 11 지원과 새로운 스위치 표현식의 preview

# Java 13

  • 기본적으로 유니코드 12.1 지원과 두 가지 새롭거나 개선된 preview 기능(향후 변경될 수 있음)이 제공

# 스위치 표현식(preview)

  • 이제 스위치 표현식이 값을 반환 가능하며 fall-through/break 문제 없이 표현식에 람다 스타일 구문을 사용 가능합니다.

스위치 표현식 전

switch(status) {
  case SUBSCRIBER:
    // code block
    break;
  case FREE_TRIAL:
    // code block
    break;
  default:
    // code block
}

스위치 표현식 후

boolean result = switch (status) {
    case SUBSCRIBER -> true;
    case FREE_TRIAL -> false;
    default -> throw new IllegalArgumentException("hello world");
};

# Multiline Strings (Preview)

스위치 표현식 전

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>
              """;

# Java 14

  • 스위치 표현식 표준화
  • instanceof 패턴 매칭 (preview)
  • record (data object) 선언 기능 추가 (preview)

# 스위치 표현(Standard)

  • 버전 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;
    }
};

# record(preview)

  • Java로 많은 상용구를 작성하는 고통을 완화하는 데 도움이 되는 레코드 클래스가 있습니다.
  • 데이터, (잠재적으로) getter/setters, equals/hashcode, toString만 포함

레코드 사용 전

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) { }

# NullPointerExceptions

  • 마지막으로 NullPointerExceptions는 정확히 어떤 변수가 null 인지 설명해줍니다.
author.age = 35;
---
Exception in thread "main" java.lang.NullPointerException:
     Cannot assign field "age" because "author" is null

# Pattern Matching For InstanceOf (Preview)

자바 14 전

if (obj instanceof String) {
    String s = (String) obj;
    // use s
}
  • 이전에는 다음과 같이 instanceof 내부에서 객체를 캐스팅이 필요합니다.

자바 14 후

if (obj instanceof String s) {
    System.out.println(s.contains("a"));
}
  • 이제 이 작업을 수행하여 캐스트를 효과적으로 삭제 가능합니다.

# Java 15

  • Text-Blocks / Multiline Strings
  • Records & Pattern Matching(2차 preview, 상단 Java 14 참조)
  • 스케일링 가능한 낮은 지연의 가비지 컬렉터 추가(ZGC)
  • 레코드 (2차 preview, 상단 Java 14 참조)
  • Sealed Classes - Preview
  • Nashorn JavaScript Engine 제거

# Text-Blocks / Multiline Strings

# Sealed Classes - Preview

  • 상속 가능한 클래스를 지정할 수 있는 봉인 클래스가 제공됩니다.
  • 상속 가능한 대상은 상위 클래스 또는 인터페이스 패키지 내에 속해 있어야 합니다.
public abstract sealed class Shape
    permits Circle, Rectangle, Square {...}

즉, 클래스가 public인 동안 하위 클래스로 허용되는 유일한 Shape 클래스들은 Circle, Rectangle 및 Square 입니다.

# Java 16

  • Pattern Matching for instanceof
  • Unix-Domain Socket Channels
  • Foreign Linker API - Preview
  • Records & Pattern Matching

# Unix-Domain Socket Channels

  • 이제 Unix 도메인 소켓에 연결할 수 있습니다(macOS 및 Windows(10+)에서도 지원됨).
socket.connect(UnixDomainSocketAddress.of("/var/run/postgresql/.s.PGSQL.5432"));

# Foreign Linker API - Preview

  • JNI(Java Native Interface)에 대한 계획된 교체로, 기본 라이브러리에 바인딩할 수 있습니다.

# Java 17

Java 17은 Java 11 이후의 새로운 Java LTS(장기 지원) 릴리스

  • Pattern Matching for switch (Preview)
  • Sealed Classes (Finalized)
  • Foreign Function & Memory API (Incubator)
  • Deprecating the Security Manager

# Pattern Matching for switch (Preview)

  • 이제 객체를 전달하여 기능을 전환하고 특정 유형을 확인할 수 있습니다.
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";
    };
}

# Sealed Classes (Finalized)

  • Java 15에서 preview 제공되었던 기능 완료

# Foreign Function & Memory API (Incubator)

  • Java Native Interface(JNI)를 대체합니다.
  • 기본 함수를 호출하고 JVM 외부의 메모리에 액세스할 수 있습니다.

# 참고자료