JavaRush /Java Blog /Random-KO /8부터 13까지: Java 버전의 전체 개요입니다. 1 부

8부터 13까지: Java 버전의 전체 개요입니다. 1 부

Random-KO 그룹에 게시되었습니다
Kittens, 안녕하세요 여러분)) 그래서 오늘은 2020년이고 Java 14 출시까지 남은 시간이 거의 없습니다. 완성된 버전은 3월 17일에 나올 것으로 예상되며, 이후에 무엇이 신선하고 흥미로운지 분석하겠지만, 오늘은 이전 버전의 Java에 대한 기억을 되짚어보고 싶습니다. 그들은 우리에게 어떤 새로운 것을 가져왔나요? 한번 살펴보자. Java 8에 대한 검토를 시작하겠습니다. Java 8은 여전히 ​​관련성이 높고 대부분의 프로젝트에서 사용되기 때문입니다. 8부터 13까지: Java 버전의 전체 개요입니다.  파트 1 - 1이전에는 3~5년마다 새 버전이 출시되었지만 최근 Oracle은 "6개월마다 새로운 Java"라는 다른 접근 방식을 취했습니다. 그래서 6개월마다 기능이 출시됩니다. 좋든 나쁘든 보는 사람마다 다르니까요. 예를 들어, 새 버전에는 새로운 기능이 많지 않지만 동시에 비가 내린 후 버전이 버섯처럼 자라기 때문에 저는 이것을 별로 좋아하지 않습니다. Java 8이 포함된 프로젝트에서 몇 번 눈을 깜박였고 Java 16은 이미 릴리스되었습니다(그러나 드물게 나오면 새로운 기능이 축적되고 결국 이 이벤트는 휴일처럼 오랫동안 기다려졌습니다. 모두가 토론하고 있습니다. 새로운 상품이 있으면 지나갈 수 없습니다). 그럼 시작해 보겠습니다!

자바 8

기능적 인터페이스

이게 뭔가요? 기능적 인터페이스는 구현되지 않은(추상) 메서드 하나를 포함하는 인터페이스입니다. @FunctionalInterface 는 이러한 인터페이스 위에 배치되는 선택적 주석입니다. 기능적 인터페이스의 요구 사항(추상 메서드가 하나만 있음)을 충족하는지 확인해야 합니다. 그러나 항상 그렇듯이 몇 가지 주의 사항이 있습니다. 기본 및 정적 메서드는 이러한 요구 사항에 속하지 않습니다. 따라서 이러한 메서드는 여러 개 + 추상 메서드 하나가 있을 수 있으며 인터페이스는 작동합니다. 또한 인터페이스를 기능적으로 정의하는 데 영향을 주지 않는 Object 클래스의 메서드를 포함할 수도 있습니다. 기본 및 정적 메서드에 대해 몇 마디 추가하겠습니다.
  1. 기본 수정자를 사용하는 메서드를 사용 하면 기존 구현을 중단하지 않고 인터페이스에 새 메서드를 추가할 수 있습니다.

    public interface Something {
      default void someMethod {
          System.out.println("Some text......");
      }
    }

    예, 예, 구현된 메서드를 인터페이스에 추가하고 이 메서드를 구현할 때 이를 재정의할 수 없지만 상속된 메서드로 사용합니다. 그러나 클래스가 주어진 메소드로 두 개의 인터페이스를 구현하면 컴파일 오류가 발생하고 인터페이스를 구현하고 동일한 특정 메소드로 클래스를 상속하는 경우 상위 클래스 메소드가 인터페이스 메소드와 겹치고 예외가 작동하지 않습니다.

  2. 인터페이스의 정적 메서드는 클래스의 정적 메서드와 동일하게 작동합니다. 잊지 마세요: 하위 클래스에서 정적 메서드를 호출할 수 없는 것처럼 정적 메서드를 상속할 수 없습니다.

이제 기능적 인터페이스에 대해 몇 마디 더 말하고 다음으로 넘어가겠습니다. FI의 주요 목록은 다음과 같습니다(나머지는 종류임).

    조건자 - 어떤 값 T를 인수로 취하고 부울을 반환합니다.

    예:boolean someMethod(T t);

  • 소비자 - T 유형의 인수를 취하고 아무것도 반환하지 않습니다(void).

    예:void someMethod(T t);

  • 공급자 - 입력으로 아무것도 사용하지 않지만 일부 값 T를 반환합니다.

    예:T someMethod();

  • 함수 - T 유형의 매개변수를 입력으로 사용하고 R 유형의 값을 반환합니다.

    예:R someMethod(T t);

  • UnaryOperator - T 인수를 사용하고 T 유형의 값을 반환합니다.

    예:T someMethod(T t);

개울

스트림은 기능적 스타일로 데이터 구조를 처리하는 방법입니다. 일반적으로 이는 컬렉션입니다(그러나 덜 일반적인 상황에서는 사용할 수 있습니다). 보다 이해하기 쉬운 언어로 말하면 Stream은 for-each와 같이 무차별 대입이 아닌 모든 데이터를 동시에 작업하는 것처럼 처리하는 데이터 스트림입니다. 작은 예를 살펴보겠습니다. 필터링하고(50개 미만) 5씩 늘리고 나머지 숫자 중 처음 4개 숫자를 콘솔에 출력하려는 ​​숫자 집합이 있다고 가정해 보겠습니다. 이전에 이 작업을 어떻게 수행했을까요?
List<Integer> list = Arrays.asList(46, 34, 24, 93, 91, 1, 34, 94);

int count = 0;

for (int x : list) {

  if (x >= 50) continue;

  x += 5;

  count++;

  if (count > 4) break;

  System.out.print(x);

}
코드가 많지 않은 것 같고, 논리도 이미 약간 혼란스럽습니다. 스트림을 사용하면 어떻게 보이는지 살펴보겠습니다.
Stream.of(46, 34, 24, 93, 91, 1, 34, 94)

      .filter(x -> x < 50)

      .map(x -> x + 5)

      .limit(4)

      .forEach(System.out::print);
스트림은 코드 양을 줄이고 가독성을 높여 삶을 크게 단순화합니다. 이 주제를 더 자세히 알아보고 싶은 분들을 위해 이 주제에 대한 좋은(훌륭하다고 말하고 싶습니다) 기사가 있습니다 .

람다

아마도 가장 중요하고 오랫동안 기다려온 기능은 람다의 등장일 것입니다. 람다 란 무엇입니까? 이는 나중에 필요한 만큼 여러 번 실행할 수 있도록 여러 위치로 전달할 수 있는 코드 블록입니다. 꽤 혼란스러울 것 같지 않나요? 간단히 말해서, 람다를 사용하면 기능적 인터페이스의 메서드(익명 클래스 구현의 일종)를 구현할 수 있습니다.
Runnable runnable = () -> { System.out.println("I'm running !");};

new Thread(runnable).start();
우리는 불필요한 관료주의 없이 신속하게 run() 메소드를 구현했습니다. 그리고 그렇습니다. Runnable은 기능적 인터페이스입니다. 또한 위의 스트림 예제에서와 같이 스트림 작업을 할 때 람다를 사용합니다. 우리는 꽤 깊이 들어갈 수 있기 때문에 너무 깊이 들어가지는 않을 것입니다. 아직 마음속으로 파고드는 사람들이 더 깊이 파고들 수 있도록 몇 개의 링크를 남겨 두겠습니다.

각각

Java 8에는 스트림과 같은 데이터 스트림에서 작동하는 새로운 foreach가 있습니다. 예는 다음과 같습니다.
List<Integer> someList = Arrays.asList(1, 3, 5, 7, 9);

someList.forEach(x -> System.out.println(x));
(someList.stream().foreach(…)와 유사)

방법 참조

참조 메소드는 ::를 통해 기존 메소드나 Java 클래스 또는 객체의 생성자를 참조하도록 설계된 새롭고 유용한 구문입니다. 메소드 참조는 네 가지 유형으로 제공됩니다.
  1. 디자이너 링크:

    SomeObject obj = SomeObject::new

  2. 정적 메소드 참조:

    SomeObject::someStaticMethod

  3. 특정 유형의 객체에 대한 비정적 메소드에 대한 참조:

    SomeObject::someMethod

  4. 특정 객체의 일반(비정적) 메서드에 대한 참조

    obj::someMethod

종종 메서드 참조는 람다 대신 스트림에서 사용됩니다(참조 메서드는 람다보다 빠르지만 가독성이 떨어집니다).
someList.stream()

        .map(String::toUpperCase)

      .forEach(System.out::println);
참조 방법에 대한 추가 정보를 원하는 경우:

API 시간

날짜 및 시간 작업을 위한 새로운 라이브러리인 java.time이 있습니다. 8부터 13까지: Java 버전의 전체 개요입니다.  파트 1 - 2새로운 API는 Joda-Time과 유사합니다. 이 API의 가장 중요한 섹션은 다음과 같습니다.
  • LocalDate 는 예를 들어 2010-01-09와 같은 특정 날짜입니다.
  • LocalTime - 시간대를 고려한 시간 - 19:45:55(LocalDate와 유사)
  • LocalDateTime - 콤보 LocalDate + LocalTime - 2020-01-04 15:37:47;
  • ZoneId - 시간대를 나타냅니다.
  • 시계 - 이 유형을 사용하면 현재 시간과 날짜에 액세스할 수 있습니다.
다음은 이 주제에 관한 매우 흥미로운 몇 가지 기사입니다.

선택 과목

이것은 java.util 패키지의 새로운 클래스로, null을 안전하게 포함할 수 있는 값 래퍼입니다 . 선택 사항 수신: Optional.ofOptional<String> someOptional = Optional.of("Something");null을 전달 하면 우리가 가장 좋아하는 NullPointerException을 받게 됩니다 . 그러한 경우에는 다음을 사용합니다. - 이 방법에서는 null을 두려워할 필요가 없습니다. 다음으로, 처음에는 비어 있는 Optional을 만듭니다. 비어 있는지 확인하려면 다음을 사용하세요. 그러면 true 또는 false가 반환됩니다. 값이 있으면 특정 작업을 수행하고 값이 없으면 아무것도 하지 않습니다. Optional이 비어 있으면 전달된 값을 반환하는 역방향 메서드(일종의 백업 계획): 아주 아주 오랫동안 계속할 수 있습니다( 다행스럽게도 Optional은 양손으로 메서드를 추가했지만 이에 대해서는 더 이상 설명하지 않겠습니다. 초보자를 위해 몇 가지 링크를 남겨 두는 것이 더 좋습니다. Optional<String> someOptional = Optional.ofNullable("Something");Optional<String> someOptional = Optional.empty();someOptional.isPresent();someOptional.ifPresent(System.out::println);System.out.println(someOptional.orElse("Some default content")); 우리는 Java 8의 가장 유명한 혁신을 살펴봤습니다. 그게 전부는 아닙니다. 더 알고 싶으시면 다음을 남겨주세요.

자바 9

그래서 2017년 9월 21일에 전 세계에 JDK 9가 공개되었습니다. 이 Java 9에는 다양한 기능이 포함되어 있습니다. 새로운 언어 개념은 없지만 새로운 API와 진단 명령은 확실히 개발자의 관심을 끌 것입니다. 8부터 13까지: Java 버전의 전체 개요입니다.  파트 1 - 4

JShell(REPL - 읽기-평가-인쇄 루프)

이는 기능을 테스트하고 콘솔에서 인터페이스, 클래스, 열거형, 연산자 등과 같은 다양한 구성을 사용하는 데 사용되는 대화형 콘솔의 Java 구현입니다. JShell을 시작하려면 터미널에 jshell을 작성하기만 하면 됩니다. 그런 다음 상상력이 허용하는 모든 것을 작성할 수 있습니다. 8부터 13까지: Java 버전의 전체 개요입니다.  파트 1 - 5JShell을 사용하면 최상위 메소드를 생성하고 동일한 세션 내에서 사용할 수 있습니다. 메소드는 static 키워드를 생략할 수 있다는 점을 제외하면 정적 메소드와 동일하게 작동합니다 . 자세한 내용은 Java 9 REPL(JShell) 매뉴얼을 참조하세요 .

사적인

Java 버전 9부터 인터페이스에서 개인 메소드를 사용할 수 있습니다(액세스 부족으로 인해 다른 메소드를 재정의할 수 없기 때문에 기본 및 정적 메소드). private static void someMethod(){} try-with-resources Try-With-Resources 예외를 처리하는 기능이 업그레이드되었습니다.
BufferedReader reader = new BufferedReader(new FileReader("....."));
  try (reader2) {
  ....
}

모듈성( 퍼즐 )

모듈은 새로운 모듈 설명자 파일과 함께 관련 패키지 및 리소스의 그룹입니다. 이 접근 방식은 코드 결합을 느슨하게 하는 데 사용됩니다. 느슨한 결합은 코드 유지 관리 및 확장성의 핵심 요소입니다. 모듈성은 다양한 수준에서 구현됩니다.
  1. 프로그래밍 언어.
  2. 가상 기기.
  3. 표준 자바 API.
JDK 9에는 92개의 모듈이 제공됩니다. 이를 사용하거나 직접 만들 수 있습니다. 더 자세히 살펴볼 수 있는 몇 가지 링크는 다음과 같습니다.

불변 컬렉션

Java 9에서는 한 줄로 컬렉션을 생성하고 채우는 동시에 불변으로 만드는 것이 가능해졌습니다(이전에는 불변 컬렉션을 생성하려면 컬렉션을 생성하고 데이터로 채우고 메서드를 호출해야 했습니다. 예: Collections.unmodifyingList). 그러한 창조의 예: List someList = List.of("first","second","third");

기타 혁신:

  • 확장됨 선택사항(새 메소드 추가됨);
  • ProcessHandle 및 ProcessHandle 인터페이스는 운영 체제의 동작을 제어하는 ​​것으로 나타났습니다.
  • G1 - 기본 가비지 수집기;
  • HTTP/2 프로토콜과 WebSocket을 모두 지원하는 HTTP 클라이언트
  • 확장된 스트림;
  • Reactive Streams API 프레임워크 추가(반응 프로그래밍용)
Java 9에 더욱 완벽하게 몰입하려면 다음 내용을 읽어 보시기 바랍니다.

자바 10

그래서 Java 9가 출시된 지 6개월 후인 2018년 3월(어제처럼 기억합니다)에 Java 10이 등장했습니다. 8부터 13까지: Java 버전의 전체 개요입니다.  파트 1 - 6

var

이제 데이터 유형을 제공할 필요가 없습니다. 메시지를 var로 표시하고 컴파일러는 오른쪽에 있는 초기화 유형에 따라 메시지 유형을 결정합니다. 이 기능은 이니셜라이저가 있는 지역 변수에만 사용할 수 있습니다. 유형을 정의할 수 있는 이니셜라이저가 없기 때문에 메서드 인수, 반환 유형 등에 사용할 수 없습니다. 예 var(문자열 유형의 경우):
var message = "Some message…..";
System.out.println(message);
var는 키워드가 아닙니다. int 와 마찬가지로 기본적으로 예약된 유형 이름입니다 . var 의 이점은 훌륭합니다. 유형 선언은 아무런 이점도 가져오지 않으면서 많은 주의를 끌며, 이 기능은 시간을 절약해 줍니다. 그러나 동시에 긴 메소드 체인에서 변수를 얻으면 어떤 종류의 객체가 있는지 즉시 알 수 없으므로 코드 읽기가 어려워집니다. 이 기능에 더 익숙해지고 싶은 사람들을 위해 바칩니다:

JIT 컴파일러(GraalVM)

더 이상 고민하지 않고 javac 명령을 실행하면 Java 애플리케이션이 Java 코드에서 애플리케이션의 이진 표현인 JVM 바이트코드로 컴파일된다는 점을 상기시켜 드리겠습니다. 그러나 일반 컴퓨터 프로세서는 단순히 JVM 바이트코드를 실행할 수 없습니다. JVM 프로그램이 작동하려면 이 바이트코드에 대한 또 다른 컴파일러가 필요합니다. 이 바이트코드는 프로세서가 이미 사용할 수 있는 기계어 코드로 변환됩니다. javac에 비해 이 컴파일러는 훨씬 더 복잡하지만 더 높은 품질의 기계 코드를 생성합니다. 현재 OpenJDK 에는 HotSpot 가상 머신이 포함되어 있으며 여기에는 두 개의 주요 JIT 컴파일러가 있습니다. 첫 번째인 C1( 클라이언트 컴파일러 )은 더 빠른 속도의 작업을 위해 설계되었지만 코드 최적화에는 어려움이 있습니다. 두 번째는 C2(서버 컴파일러)입니다. 실행 속도는 떨어지지만 코드는 더 최적화됩니다. 어느 것이 언제 사용됩니까? C1은 긴 JIT 일시 중지가 바람직하지 않은 데스크톱 애플리케이션에 적합하고 C2는 컴파일에 더 많은 시간을 소비하는 것이 상당히 견딜 수 있는 장기 실행 서버 프로그램에 적합합니다. 다단계 컴파일은 컴파일이 먼저 C1을 거치고 그 결과가 C2를 거치는 것입니다(더 나은 최적화를 위해 사용됨). GraalVM은 HotSpot을 완전히 대체하기 위해 만들어진 프로젝트입니다. Graal은 HotSpot을 위한 새로운 JIT 컴파일러와 새로운 다중 언어 가상 머신 등 여러 관련 프로젝트로 생각할 수 있습니다. 이 JIT 컴파일러의 특징은 Java로 작성된다는 것입니다. Graal 컴파일러의 장점은 안전입니다. 즉, 충돌이 아니라 예외가 발생하고 메모리 누수가 발생하지 않습니다. 우리는 또한 훌륭한 IDE 지원을 받게 될 것이며 디버거, 프로파일러 또는 기타 편리한 도구를 사용할 수 있을 것입니다. 또한 컴파일러는 HotSpot과 독립적일 수 있으며 자체적으로 더 빠른 JIT 컴파일 버전을 생성할 수 있습니다. 굴착기의 경우:

병렬 G1

G1 가비지 수집기는 확실히 멋지지만 의심의 여지가 없지만 약점도 있습니다. 단일 스레드 전체 GC 주기를 수행합니다. 사용되지 않는 개체를 찾기 위해 하드웨어의 모든 성능이 필요할 때 우리는 단일 스레드로 제한됩니다. Java 10에서는 이 문제가 해결되었으며 이제 GC는 우리가 추가한 모든 리소스와 함께 작동합니다(즉, 멀티스레드가 됩니다). 이를 달성하기 위해 언어 개발자는 GC에서 기본 소스의 격리를 개선하여 GC를 위한 멋지고 깔끔한 인터페이스를 만들었습니다. 이 귀여운 개발자인 OpenJDK는 새 GC 생성을 최대한 단순화할 뿐만 아니라 어셈블리에서 불필요한 GC를 신속하게 비활성화할 수 있도록 코드에서 덤프를 구체적으로 정리해야 했습니다. 성공의 주요 기준 중 하나는 이러한 모든 개선 후에도 작동 속도가 저하되지 않는다는 것입니다. 또한 살펴보겠습니다: 기타 혁신:
  1. 깨끗한 가비지 수집기 인터페이스가 도입되었습니다. 이는 다른 가비지 수집기로부터 소스 코드의 격리를 향상시켜 대체 수집기를 빠르고 쉽게 통합할 수 있게 해줍니다.
  2. JDK 소스를 하나의 저장소로 결합합니다.
  3. 컬렉션은 이 컬렉션의 변경 불가능한 복사본을 반환하는 copyOf(Collection) 라는 새로운 메서드를 받았습니다 .
  4. Optional (및 그 변형)에는 새로운 메서드 .orElseThrow() 가 있습니다 .
  5. 이제부터 JVM은 Docker 컨테이너에서 실행되고 있음을 인식하고 운영 체제 자체를 쿼리하는 대신 컨테이너별 구성을 검색합니다.
다음은 Java 10에 대한 자세한 소개를 위한 추가 자료입니다. 나는 Java의 일부 버전이 1.x라고 불린다는 사실 때문에 매우 혼란스러웠습니다. 명확하게 말하고 싶습니다. 9 이전의 Java 버전은 단순히 다른 이름 지정 체계를 가졌습니다. 예를 들어 Java 8은 1.8 , Java 5 - 1.5 등 으로 불릴 수도 있습니다 . 이제 Java 9에서 릴리스로 전환하면서 명명 체계도 변경되었으며 Java 버전에는 더 이상 1.x 접두사가 붙지 않습니다. . 이것이 첫 번째 부분의 끝입니다. 우리는 Java 8-10의 새로운 흥미로운 기능을 살펴보았습니다. 다음 게시물 에서 최신 소식을 계속 알아 보겠습니다 .
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION