java 버전별 차이 & 특징

이주오·2022년 1월 12일
26

java

목록 보기
3/6
post-thumbnail

Java 버전별 특징들을 찾아보면서 좋은 글이 있어 해당 글을 정리한 포스팅입니다.
따라서 잘못된 내용이 존재할 수 있습니다!

어떤 자바 버전을 사용해야 할까?

최신 Java 버전은 이제 6개월마다 따른다.

수많은 새로운 버전이 출시됨에 따라 기본적으로 다음과 같은 사용 시나리오가 존재

  • 기업의 기존 프로젝트에서는 Java 8을 사용해야 하는 경우가 많음
  • 일부 레거시 프로젝트는 Java 1.5(2004년 출시) 또는 1.6(2006년 출시)에서 중단되기도 함
  • 최신 IDE, 프레임워크 및 빌드 도구를 사용하고 그린 필드 프로젝트를 시작하는 경우 Java 11(LTS) 또는 최신 Java 17 LTS를 망설임 없이 사용할 수 있다.
  • 안드로이드 개발의 특별한 분야가 있는데, 자바 버전은 기본적으로 자바 7에 고정되어 있고, 특정한 자바 8 기능들을 이용할 수 있다. 또는 코틀린 프로그래밍 언어를 사용하는 것으로 전환

특정 자바 버전을 학습해야 할까?

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에 추가된 기능에 대해 알아보고 언제든지 사용할 수 있다.


자바 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

java8-17 특징


java 8

Java 8은 대규모 릴리스였으며 Oracle 웹 사이트 에서 모든 기능 목록을 확인 가능

  • Lambda,
  • stream
  • interface default method
  • Optional
  • new Date and Time API(LocalDateTime, …)

Lambda

Java 8 이전 익명 클래스의 사용을 람다를 이용하여 더욱 간결하고 직관적으로 구현 가능

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

Stream

자바 8은 스트림 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);

Java 9

Java 9는 다음과 같은 몇 가지 추가 사항이 포함된 상당히 큰 릴리스

  • 모듈시스템 등장(jigsaw)

컬렉션

컬렉션에는 list, set, map을 쉽게 구성할 수 있는 몇 가지 추가 기능

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

스트림

takeWhile, dropWhile, iterate 메서드의 형태로 몇 가지 추가 기능

Stream<String> stream = Stream.iterate(*""*, s -> s + *"s"*)
  .takeWhile(s -> s.length() < 10);

optional

ifPresentOrElse 추가 기능

user.ifPresentOrElse(this::displayAccount, this::displayLogin);

인터페이스

인터페이스에 private method 사용 가능

public interface MyInterface {

    private static void myPrivateMethod(){
        System.out.println(*"Yay, I am private!"*);
    }
}

기타 언어 기능

try-with-resources 문 또는 다이아몬드 연산자(<>) 확장, HTTP클라이언트와 같은 몇 가지 다른 개선 사항 존재


Java 10

가비지 컬렉션 등과 같은 Java 10에 몇 가지 변경 사항이 존재

개발자로서 보게 될 유일한 실제 변경 사항은 로컬 변수 유형 추론이라고도 하는 "var" 키워드의 도입

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

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

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

// With Java 10
var myName = "Marco"

JAVA에서 var 예약어를 사용하면 중복을 줄임으로써 코드를 간결하게 만들 수 있다. 

  • var 키워드는 지역 변수 타입 추론을 허용한다.
  • 메서드 내부의 변수에만 적용 가능

Java 11

Java 11은 개발자의 관점에서 볼 때 약간 작은 릴리스

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

Strings & 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);

Run Source Files

Java 10부터 Java 소스 파일 을 먼저 컴파일 하지 않고도 실행할 수 있다. 스크립팅을 향한 한 걸음

ubuntu@DESKTOP-168M0IF:~$ java MyScript.java

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

람다 표현식에 var 사용 가능

(var firstName, var lastName) -> firstName + lastName

Java 12

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(*"something is murky!"*);
};

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

자바 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만 포함하는 이 Java 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) { }

유용한 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)

이전에는 다음과 같이 instanceof 내부에서 객체를 캐스팅 필요

if (obj instanceof String) {
    String s = (String) obj;
    *// use s*}

이제 이 작업을 수행하여 캐스트를 효과적으로 삭제 가능

if (obj instanceof String s) {
    System.out.println(s.contains(*"hello"*));
}

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

Java 13의 실험 기능으로 도입된 여러 줄 문자열은 이제 프로덕션 준비 완료

String text = *"""
                Lorem ipsum dolor sit amet, consectetur adipiscing \
                elit, sed do eiusmod tempor incididunt ut labore \
                et dolore magna aliqua.\
                """*;

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)에 대한 계획된 교체로, 기본 라이브러리에 바인딩할 수 있다(C 생각).


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 외부의 메모리에 액세스할 수 있다. 지금은 C가 C++, 포트란과 같은 추가 언어 지원 계획을 가지고 있다고 생각

Deprecating the Security Manager

자바 1.0 이후로 보안 관리자가 존재해 왔었지만 현재는 더 이상 사용되지 않으며 향후 버전에서는 제거될 예정


참고 출처

profile
동료들이 같이 일하고 싶어하는 백엔드 개발자가 되고자 합니다!

0개의 댓글