ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๋ฐ˜์‘ํ˜•

โœ… Java 8~21 ๋ฒ„์ „๋ณ„ ์ฐจ์ด์ 

https://www.java.com/releases/

 

JDK Releases

The release information on this page covers the JDK releases that were widely distributed or significant to the development of Java. It does not cover patch releases or other one-off releases.

www.java.com

 

Java 8 (2014๋…„ ์ถœ์‹œ)

Java 8์€ Java ์–ธ์–ด์— ํฐ ๋ณ€ํ™”๋ฅผ ๊ฐ€์ ธ์˜จ ๋ฒ„์ „์œผ๋กœ, ์ดํ›„์˜ ๋งŽ์€ ๊ธฐ๋Šฅ๋“ค์ด Java 8์˜ ๊ธฐ๋Šฅ์— ๊ธฐ๋ฐ˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  • 32๋น„ํŠธ๋ฅผ ์ง€์›ํ•˜๋Š” ๊ณต์‹์ ์ธ ๋งˆ์ง€๋ง‰ ๋ฒ„์ „
  • ๋žŒ๋‹ค ํ‘œํ˜„์‹ (Lambda Expressions): ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๋„์ž…ํ•˜์—ฌ ์ฝ”๋“œ ๊ฐ„๊ฒฐํ™”.
  • ์ŠคํŠธ๋ฆผ API (Stream API): ์ปฌ๋ ‰์…˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์„ ์–ธํ˜• API๋กœ, ํ•„ํ„ฐ๋ง, ๋งคํ•‘, ์ถ•์†Œ(reduction) ๋“ฑ์˜ ์ž‘์—…์„ ๋” ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰.
  • ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ (Default Methods): ์ธํ„ฐํŽ˜์ด์Šค์— ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉ.
  • Optional ํด๋ž˜์Šค: NullPointerException ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด ๋ž˜ํ•‘ ํด๋ž˜์Šค.
  • ์ƒˆ๋กœ์šด ๋‚ ์งœ ๋ฐ ์‹œ๊ฐ„ API: java.time ํŒจํ‚ค์ง€๋ฅผ ํ†ตํ•ด ๋” ๋‚˜์€ ๋‚ ์งœ ๋ฐ ์‹œ๊ฐ„ ์ฒ˜๋ฆฌ๋ฅผ ์ œ๊ณต.
  • Perm Gem ์˜์—ญ์‚ญ์ œ (์ฐธ๊ณ  : https://johngrib.github.io/wiki/java8-why-permgen-removed/)

1. ๋žŒ๋‹คํ‘œํ˜„์‹

public class ExampleLambda {
	public static void main(String[] args) {
    	List<String> names = Arrays.asList("Park", "Kim", "Choi", "Lee");
        
        // ๋žŒ๋‹ค ํ‘œํ˜„์‹
        names.forEach(name -> System.out.println(name));
    }
}

2. ์ŠคํŠธ๋ฆผAPI

public class ExampleStream {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // ์ŠคํŠธ๋ฆผ์„ ์ด์šฉํ•œ ํ•„ํ„ฐ๋ง๊ณผ ์ถœ๋ ฅ
        numbers.stream()
               .filter(n -> n % 2 == 0) // ์ง์ˆ˜๋งŒ ํ•„ํ„ฐ๋ง
               .forEach(System.out::println);
    }
}

3. ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋””ํดํŠธ ๋ฉ”์†Œ๋“œ

interface MyInterface {
    default void defaultMethod() {
        System.out.println("This is a default method");
    }
}

public class DefaultMethodExample implements MyInterface {
    public static void main(String[] args) {
        DefaultMethodExample obj = new DefaultMethodExample();
        obj.defaultMethod(); // ๋””ํดํŠธ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ
    }
}

4. ์ƒˆ๋กœ์šด ๋‚ ์งœ์™€ ์‹œ๊ฐ„ API

public class ExampleDateTime {
    public static void main(String[] args) {
        LocalDate date = LocalDate.now();
        System.out.println("ํ˜„์žฌ ๋‚ ์งœ: " + date);

        LocalTime time = LocalTime.now();
        System.out.println("ํ˜„์žฌ ์‹œ๊ฐ„: " + time);

        LocalDateTime dateTime = LocalDateTime.now();
        System.out.println("ํ˜„์žฌ ๋‚ ์งœ์™€ ์‹œ๊ฐ„: " + dateTime);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedDateTime = dateTime.format(formatter);
        System.out.println("ํ˜•์‹ํ™”๋œ ๋‚ ์งœ์™€ ์‹œ๊ฐ„: " + formattedDateTime);
    }
}

5. Optionalํด๋ž˜์Šค

public class ExampleOptional {
    public static void main(String[] args) {
        String name = "John";
        Optional<String> optionalName = Optional.ofNullable(name);
        
        System.out.println("์ด๋ฆ„ ๊ธธ์ด: " + optionalName.map(String::length).orElse(0));
        
        String nullName = null;
        Optional<String> optionalNullName = Optional.ofNullable(nullName);
        
        System.out.println("Null ์ด๋ฆ„ ๊ธธ์ด: " + optionalNullName.map(String::length).orElse(0));
    }
}

Java 9 (2017๋…„ ์ถœ์‹œ)

Java 9์—์„œ๋Š” ์ฃผ์š”ํ•œ ์‹œ์Šคํ…œ์ ์ธ ๋ณ€ํ™”๊ฐ€ ์žˆ์—ˆ์œผ๋ฉฐ, ํŠนํžˆ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ ๋„์ž…์ด ํฐ ๋ณ€ํ™”์˜€์Šต๋‹ˆ๋‹ค.

  • ๋ชจ๋“ˆ ์‹œ์Šคํ…œ (Project Jigsaw): ๋Œ€๊ทœ๋ชจ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ชจ๋“ˆํ™”ํ•  ์ˆ˜ ์žˆ๋Š” module-info.java ๋„์ž….
  • JShell: ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒํ•œ REPL(Read-Eval-Print Loop) ๋„๊ตฌ๋กœ, Java ์ฝ”๋“œ๋ฅผ ๋ฐ”๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•จ.
  • ์ŠคํŠธ๋ฆผ API ๊ฐœ์„ : takeWhile(), dropWhile(), iterate() ๋“ฑ์˜ ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€.
  • HTTP/2 ํด๋ผ์ด์–ธํŠธ: ๋น„๋™๊ธฐ HTTP/2 ํ˜ธ์ถœ์„ ์ง€์›ํ•˜๋Š” ์ƒˆ HTTP ํด๋ผ์ด์–ธํŠธ API ๋„์ž….

1. ๋ชจ๋“ˆ ์‹œ์Šคํ…œ

// module-info.java ํŒŒ์ผ์„ ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— ์ƒ์„ฑ
module mymodule {
    exports com.example.mymodule;
}

// ๋ชจ๋“ˆ์‚ฌ์šฉ์˜ˆ์‹œ
package com.example.mymodule;

public class MyModuleClass {
    public static void sayHello() {
        System.out.println("Hello from mymodule!");
    }
}

// ๋ชจ๋“ˆ์„ ํ†ตํ•ด์„œ ์„œ๋กœ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€ ๊ฐ„ ์˜์กด์„ฑ์„ ๊ด€๋ฆฌํ•˜๊ณ  ์ ‘๊ทผ ๋ฒ”์œ„๋ฅผ ์ œ์–ดํ• ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2. ์ธํ„ฐํŽ˜์ด์Šค์˜ private๋ฉ”์†Œ๋“œ

- Java9๋ถ€ํ„ฐ ์ธํ„ฐํŽ˜์ด์Šค์— private๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ• ์ˆ˜ ์žˆ์–ด์„œ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์ด ๋” ์šฉ์ดํ•ด์ง

interface MyInterface {
    default void method1() {
        System.out.println("Method 1");
        commonMethod();
    }

    default void method2() {
        System.out.println("Method 2");
        commonMethod();
    }

    // private ๋ฉ”์†Œ๋“œ ์ •์˜
    private void commonMethod() {
        System.out.println("This is a common method");
    }
}

public class PrivateMethodInInterfaceExample implements MyInterface {
    public static void main(String[] args) {
        PrivateMethodInInterfaceExample obj = new PrivateMethodInInterfaceExample();
        obj.method1();
        obj.method2();
    }
}

3. Stream API ๊ฐœ์„ 

- Java 9์—์„œ๋Š” takeWhile, dropWhile, iterate ๋“ฑ์˜ ์ƒˆ๋กœ์šด ๋ฉ”์†Œ๋“œ๊ฐ€ Stream API์— ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

public class StreamAPIExample {
    public static void main(String[] args) {
        // takeWhile ์˜ˆ์ œ
        Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
              .takeWhile(n -> n < 5) // ์กฐ๊ฑด์ด true์ธ ๋™์•ˆ๋งŒ ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์˜ด
              .forEach(System.out::println);

        // dropWhile ์˜ˆ์ œ
        Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
              .dropWhile(n -> n < 5) // ์กฐ๊ฑด์ด true์ธ ๋™์•ˆ์€ ๊ฑด๋„ˆ๋›ฐ๊ณ  ๋‚˜๋จธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ด
              .forEach(System.out::println);
    }
}

4. Optional ํด๋ž˜์Šค ๊ฐœ์„ 

- ifPresentOrElse, or, stream ๋“ฑ์˜ ์ƒˆ๋กœ์šด ๋ฉ”์†Œ๋“œ๊ฐ€ ์ถ”๊ฐ€

public class OptionalExample {
    public static void main(String[] args) {
        Optional<String> optionalValue = Optional.of("Hello");

        // ifPresentOrElse ๋ฉ”์†Œ๋“œ
        optionalValue.ifPresentOrElse(
            System.out::println, 
            () -> System.out.println("Value is absent")
        );

        // stream ๋ฉ”์†Œ๋“œ
        optionalValue.stream()
                     .forEach(System.out::println);
    }
}

5. try-with-resources ๊ฐœ์„ 

public class TryWithResourcesExample {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader("test.txt"));

        // ์ด๋ฏธ ์„ ์–ธ๋œ ๋ฆฌ์†Œ์Šค๋ฅผ try-with-resources์—์„œ ์‚ฌ์šฉ
        try (reader) {
            System.out.println(reader.readLine());
        }
    }
}

 

Java 10 (2018๋…„ ์ถœ์‹œ)

Java 10์€ ์งง์€ ๋ฆด๋ฆฌ์Šค ์ฃผ๊ธฐ๋กœ ์ œ๊ณต๋˜์—ˆ์œผ๋ฉฐ, ์ฃผ๋กœ ์„ฑ๋Šฅ ํ–ฅ์ƒ ๋ฐ ๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜ ๊ฐœ์„ ์— ์ดˆ์ ์„ ๋งž์ท„์Šต๋‹ˆ๋‹ค.

  • ์ง€์—ญ ๋ณ€์ˆ˜ ํƒ€์ž… ์ถ”๋ก  (var): ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™์œผ๋กœ ๋ณ€์ˆ˜ ํƒ€์ž…์„ ์ถ”๋ก ํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ํƒ€์ž…์„ ์„ ์–ธํ•  ํ•„์š”๊ฐ€ ์—†์Œ.
  • Garbage Collector ๊ฐœ์„ : G1 GC๋ฅผ ๊ธฐ๋ณธ GC๋กœ ์ง€์ •ํ•˜๊ณ  ์„ฑ๋Šฅ ์ตœ์ ํ™”.

1. varํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•œ ์ง€์—ญ๋ณ€์ˆ˜ ํƒ€์ž… ์ถ”๋ก 

public class ExampleVar {
    public static void main(String[] args) {
        // var ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ž… ์ถ”๋ก 
        var message = "Hello, Java 10!";
        System.out.println(message);

        var numbers = List.of(1, 2, 3, 4, 5);
        System.out.println("List: " + numbers);

        var list = new ArrayList<String>();
        list.add("Java");
        list.add("10");
        System.out.println("ArrayList: " + list);
    }
}

2. List.copyOf(), Set.copyOf(), Map.copyOf() ๋ฉ”์†Œ๋“œ

- ์ปฌ๋ ‰์…˜์„ ๋ณต์‚ฌํ•˜์—ฌ ๋ถˆ๋ณ€ ์ปฌ๋ ‰์…˜์„ ์ƒ์„ฑํ•˜๋Š” ๋ฉ”์†Œ๋“œ๊ฐ€ ์ถ”๊ฐ€

public class CopyOfExample {
    public static void main(String[] args) {
        // ๊ธฐ์กด ๋ฆฌ์ŠคํŠธ ๋ณต์‚ฌํ•˜์—ฌ ๋ถˆ๋ณ€ ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ
        List<Integer> originalList = List.of(1, 2, 3);
        List<Integer> copyList = List.copyOf(originalList);
        System.out.println("List.copyOf: " + copyList);

        // ๊ธฐ์กด ์…‹ ๋ณต์‚ฌํ•˜์—ฌ ๋ถˆ๋ณ€ ์…‹ ์ƒ์„ฑ
        Set<String> originalSet = Set.of("A", "B", "C");
        Set<String> copySet = Set.copyOf(originalSet);
        System.out.println("Set.copyOf: " + copySet);

        // ๊ธฐ์กด ๋งต ๋ณต์‚ฌํ•˜์—ฌ ๋ถˆ๋ณ€ ๋งต ์ƒ์„ฑ
        Map<String, Integer> originalMap = Map.of("one", 1, "two", 2);
        Map<String, Integer> copyMap = Map.copyOf(originalMap);
        System.out.println("Map.copyOf: " + copyMap);
    }
}

3. Optional.orElseThrow() ๋ฉ”์†Œ๋“œ

public class OptionalExample {
    public static void main(String[] args) {
        Optional<String> optional = Optional.of("Hello, Java 10!");

        // ๊ฐ’์ด ์—†์„ ๋•Œ NoSuchElementException์„ ๋˜์ง
        String value = optional.orElseThrow();
        System.out.println(value);
    }
}

4. Collectors.toUnmodifiableList(), Collectors.toUnmodifiableSet(), Collectors.toUnmodifiableMap()

- Java 10์—์„œ๋Š” ์ŠคํŠธ๋ฆผ ์ฒ˜๋ฆฌ ์ค‘ ๊ฒฐ๊ณผ๋ฅผ ๋ถˆ๋ณ€ ์ปฌ๋ ‰์…˜์œผ๋กœ ์ˆ˜์ง‘ํ•˜๋Š” ์ƒˆ๋กœ์šด Collectors ๋ฉ”์†Œ๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ˆ˜์ง‘๋œ ์ปฌ๋ ‰์…˜์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

public class UnmodifiableCollectorsExample {
    public static void main(String[] args) {
        // ์ŠคํŠธ๋ฆผ์„ ๋ถˆ๋ณ€ ๋ฆฌ์ŠคํŠธ๋กœ ์ˆ˜์ง‘
        List<String> unmodifiableList = Stream.of("A", "B", "C")
                                              .collect(Collectors.toUnmodifiableList());

        System.out.println("Unmodifiable List: " + unmodifiableList);

        // ๋ฆฌ์ŠคํŠธ์— ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ํ•˜๋ฉด UnsupportedOperationException ๋ฐœ์ƒ
        // unmodifiableList.add("D"); // ์‹คํ–‰ ์‹œ ์˜ˆ์™ธ ๋ฐœ์ƒ
    }
}

5. G1 ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ์˜ ํ–ฅ์ƒ๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ

 - G1 ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ๊ธฐ๋ณธ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋กœ ์„ค์ •๋˜์—ˆ์œผ๋ฉฐ, ์ „์ฒด ํž™ ์˜์—ญ์„ ๋™์ ์œผ๋กœ ํ• ๋‹นํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์ด ๋”์šฑ ํšจ์œจ์ ์ด๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

Java 11 (2018๋…„ ์ถœ์‹œ, LTS)

Java 11์€ ์žฅ๊ธฐ ์ง€์›(Long-Term Support, LTS) ๋ฒ„์ „์œผ๋กœ, ์•ˆ์ •์„ฑ๊ณผ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์—ฌ ๋งŽ์€ ๊ธฐ์—…์—์„œ ๋„๋ฆฌ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • Open JDK์™€ Oracle JDK ํ†ตํ•ฉ
  • ๋žŒ๋‹ค ์ง€์—ญ ๋ณ€์ˆ˜ ์‚ฌ์šฉ ๋ฐฉ๋ฒ• ๋ณ€๊ฒฝ (var)
  • ์ƒˆ๋กœ์šด HTTP ํด๋ผ์ด์–ธํŠธ API (HTTP/2 ์ง€์›): HTTP/2 ๋ฐ WebSocket์„ ์ง€์›ํ•˜๋Š” ์ƒˆ ํด๋ผ์ด์–ธํŠธ API๊ฐ€ ์ •์‹์œผ๋กœ ๋„์ž…๋จ.
    - ๋ฒ„์ „11 ๋ถ€ํ„ฐ Java Http Client API๋Š” ์ตœ์‹  HTTP ํ‘œ์ค€ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ๋™๊ธฐ ๋ฐ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ์ธ HTTP/1.1 ๋ฐ HTTP/2๋ฅผ ์ง€์›ํ•จ
  • ์ƒˆ๋กœ์šด String ๋ฉ”์„œ๋“œ: isBlank(), lines(), repeat(), strip() ๋“ฑ์˜ ์œ ์šฉํ•œ String ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€.
  • ํ‘œ์ค€ํ™”๋œ ๋Ÿฐํƒ€์ž„ ๋กœ๋“œ ๊ฐ€๋Šฅ์„ฑ: Java ๋Ÿฐํƒ€์ž„์—์„œ dynamic ํด๋ž˜์Šค ํŒŒ์ผ์„ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ ์ถ”๊ฐ€.
  • ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ์ผ๋ถ€๋กœ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” Java ๋Ÿฐํƒ€์ž„: ๊ธฐ์กด์˜ java --add-modules๋กœ ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ์„ ์กฐํ•ฉ ๊ฐ€๋Šฅ.

1. var๋ฅผ ์‚ฌ์šฉํ•œ ๋žŒ๋‹ค ํ‘œํ˜„์‹์˜ ์ง€์—ญ ๋ณ€์ˆ˜ ํƒ€์ž… ์ถ”๋ก 

public class LambdaVarExample {
    public static void main(String[] args) {
        BiFunction<Integer, Integer, Integer> add = (var a, var b) -> a + b;
        System.out.println(add.apply(10, 20));  // ์ถœ๋ ฅ: 30
    }
}

2. ์ƒˆ๋กœ์šด String ๋ฉ”์†Œ๋“œ

public class StringMethodsExample {
    public static void main(String[] args) {
        String str = "  Hello Java 11!  ";

        // isBlank() ๋ฉ”์†Œ๋“œ
        System.out.println("".isBlank());  // ์ถœ๋ ฅ: true

        // strip() ๋ฉ”์†Œ๋“œ
        System.out.println("[" + str.strip() + "]");  // ์ถœ๋ ฅ: [Hello Java 11!]

        // lines() ๋ฉ”์†Œ๋“œ
        String multiLineStr = "Hello\nJava 11\n!";
        multiLineStr.lines().forEach(System.out::println);  
        // ์ถœ๋ ฅ:
        // Hello
        // Java 11
        // !

        // repeat() ๋ฉ”์†Œ๋“œ
        String repeated = "Hello ".repeat(3);
        System.out.println(repeated);  // ์ถœ๋ ฅ: Hello Hello Hello 
    }
}

3. HTTP Client ํ‘œ์ค€ํ™”

public class HttpClientExample {
    public static void main(String[] args) throws IOException, InterruptedException {
        // HttpClient ์ƒ์„ฑ
        HttpClient client = HttpClient.newHttpClient();

        // ์š”์ฒญ ์ƒ์„ฑ
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://postman-echo.com/get"))
                .build();

        // ์‘๋‹ต ๋ฐ›๊ธฐ
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // ์‘๋‹ต ๋‚ด์šฉ ์ถœ๋ ฅ
        System.out.println(response.body());
    }
}

4. ํŒŒ์ผ ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ ๊ฐ„์†Œํ™”

public class FileReadWriteExample {
    public static void main(String[] args) throws IOException {
        Path filePath = Path.of("example.txt");

        // ํŒŒ์ผ์— ๋ฌธ์ž์—ด ์“ฐ๊ธฐ
        Files.writeString(filePath, "Hello, Java 11!");

        // ํŒŒ์ผ์—์„œ ๋ฌธ์ž์—ด ์ฝ๊ธฐ
        String content = Files.readString(filePath);
        System.out.println(content);  // ์ถœ๋ ฅ: Hello, Java 11!
    }
}

5. Optional ํด๋ž˜์Šค์˜ isEmpty() ๋ฉ”์†Œ๋“œ ์ถ”๊ฐ€

public class OptionalExample {
    public static void main(String[] args) {
        Optional<String> optional = Optional.ofNullable(null);

        // isEmpty() ๋ฉ”์†Œ๋“œ ์‚ฌ์šฉ
        if (optional.isEmpty()) {
            System.out.println("Optional is empty!");  // ์ถœ๋ ฅ: Optional is empty!
        }
    }
}

6. Java EE์™€ CORBA ๋ชจ๋“ˆ ์ œ๊ฑฐ

- 11์—์„œ๋Š” ์ž๋ฐ” EE ๋ฐ CORBA ๊ด€๋ จ ๋ชจ๋“ˆ์ด ๋” ์ด์ƒ ํฌํ•จ๋˜์ง€ ์•Š์œผ๋ฉฐ, ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ ์—”์ง„ ์‚ฌ์šฉ๋„ ์ค‘๋‹จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ชจ๋“ˆ๋“ค์€ ์ž์ฃผ ์‚ฌ์šฉ๋˜์ง€ ์•Š์œผ๋ฉฐ, ํ•„์š”ํ•  ๊ฒฝ์šฐ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋Œ€์ฒด ๊ฐ€๋Šฅ

Java 12 (2019๋…„ ์ถœ์‹œ)

Java 12๋Š” ์„ฑ๋Šฅ ๋ฐ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ ์‹คํ—˜์ ์œผ๋กœ ๋„์ž…ํ•œ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค.

  • Switch Expressions (๋ฏธ๋ฆฌ๋ณด๊ธฐ ๊ธฐ๋Šฅ): switch ๋ฌธ์„ ํ‘œํ˜„์‹์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ.
  • Garbage Collector ๊ฐœ์„ : G1 GC์— ๋Œ€ํ•œ ์„ฑ๋Šฅ ๊ฐœ์„  ๋ฐ Shenandoah GC ์ถ”๊ฐ€.

1. switch ํ‘œํ˜„์‹ (Switch Expressions) - ํ”„๋ฆฌ๋ทฐ ๊ธฐ๋Šฅ

public class SwitchExpressionExample {
    public static void main(String[] args) {
        int day = 2;

        // Java 12์˜ switch ํ‘œํ˜„์‹
        String dayName = switch (day) {
            case 1 -> "Sunday";
            case 2 -> "Monday";
            case 3 -> "Tuesday";
            case 4 -> "Wednesday";
            case 5 -> "Thursday";
            case 6 -> "Friday";
            case 7 -> "Saturday";
            default -> throw new IllegalArgumentException("Invalid day: " + day);
        };

        System.out.println("Day " + day + " is " + dayName);
    }
}

2. Collectors.teeing() ๋ฉ”์†Œ๋“œ

public class TeeingCollectorExample {
    public static void main(String[] args) {
        List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // ํ‰๊ท ๊ณผ ํ•ฉ์„ ๋™์‹œ์— ๊ณ„์‚ฐ
        var result = numbers.stream()
            .collect(Collectors.teeing(
                Collectors.summingInt(Integer::intValue),
                Collectors.averagingInt(Integer::intValue),
                (sum, avg) -> "Sum: " + sum + ", Average: " + avg
            ));

        System.out.println(result);  // ์ถœ๋ ฅ: Sum: 55, Average: 5.5
    }
}

3. ์ƒˆ๋กœ์šด String ๋ฉ”์†Œ๋“œ (indent, transform)

public class StringMethodsExample {
    public static void main(String[] args) {
        String text = "Hello\nJava 12!";

        // indent() ๋ฉ”์†Œ๋“œ
        String indented = text.indent(4);
        System.out.println("Indented Text: ");
        System.out.println(indented);

        // transform() ๋ฉ”์†Œ๋“œ
        String transformed = text.transform(str -> str.toUpperCase());
        System.out.println("Transformed Text: " + transformed);  // ์ถœ๋ ฅ: HELLO\nJAVA 12!
    }
}

4. ํŒŒ์ผ ๋ฐ ํ”„๋กœ์„ธ์Šค API ๊ฐœ์„ 

public class FileMismatchExample {
    public static void main(String[] args) throws IOException {
        Path file1 = Files.writeString(Files.createTempFile("file1", ".txt"), "Hello Java 12");
        Path file2 = Files.writeString(Files.createTempFile("file2", ".txt"), "Hello Java 11");

        // ๋‘ ํŒŒ์ผ์˜ ๋ถˆ์ผ์น˜ ์œ„์น˜ ์ฐพ๊ธฐ
        long mismatch = Files.mismatch(file1, file2);
        System.out.println("Mismatch at byte position: " + mismatch);  // ์ถœ๋ ฅ: Mismatch at byte position: 9
    }
}

5. Shenandoah ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ

- ์ƒˆ๋กœ์šด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ์ธ Shenandoah๊ฐ€ ์‹คํ—˜์ ์œผ๋กœ ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Shenandoah๋Š” ์งง์€ GC ์ง€์—ฐ ์‹œ๊ฐ„์— ์ค‘์ ์„ ๋‘” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ์ž…๋‹ˆ๋‹ค. ์ด ์˜ˆ์ œ๋Š” Shenandoah GC๋ฅผ ์ง์ ‘ ๋ณด์—ฌ์ฃผ์ง€ ์•Š์ง€๋งŒ, GC๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

6. JVM ๊ฐœ์„  ์‚ฌํ•ญ

- JVM์— ๋ช‡ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ๊ฐœ์„  ์‚ฌํ•ญ์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ค‘ ํ•˜๋‚˜๋Š” JEP 346: Promptly Return Unused Committed Memory์ž…๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ JVM์ด ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‹œ์Šคํ…œ์— ๋น ๋ฅด๊ฒŒ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ํŠนํžˆ ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ์„ ๋†’์ด๋Š”๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค

Java 13 (2019๋…„ ์ถœ์‹œ)

Java 13์€ ๊ฐ„๋‹จํ•œ ๊ฐœ์„  ์‚ฌํ•ญ๋“ค์„ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ํ…์ŠคํŠธ ๋ธ”๋ก (Text Blocks, ๋ฏธ๋ฆฌ๋ณด๊ธฐ): ์—ฌ๋Ÿฌ ์ค„์˜ ๋ฌธ์ž์—ด์„ ๋”์šฑ ๊ฐ€๋…์„ฑ ์žˆ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ.
  • Switch Expressions (๋ฏธ๋ฆฌ๋ณด๊ธฐ): Switch ํ‘œํ˜„์‹์ด ๋”์šฑ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๊ฐœ์„ ๋จ.

1. ํ…์ŠคํŠธ ๋ธ”๋ก (Text Blocks) - ํ”„๋ฆฌ๋ทฐ ๊ธฐ๋Šฅ

public class TextBlockExample {
    public static void main(String[] args) {
        String textBlock = """
                Hello, Java 13!
                This is a text block.
                It makes multi-line strings easier to write.
                """;

        System.out.println(textBlock);
    }
}

2. switch ํ‘œํ˜„์‹์˜ ์ •์‹ ๋„์ž…

public class SwitchExpressionExample {
    public static void main(String[] args) {
        int day = 2;

        // Java 13์˜ switch ํ‘œํ˜„์‹
        String dayName = switch (day) {
            case 1 -> "Sunday";
            case 2 -> "Monday";
            case 3 -> "Tuesday";
            case 4 -> "Wednesday";
            case 5 -> "Thursday";
            case 6 -> "Friday";
            case 7 -> "Saturday";
            default -> throw new IllegalArgumentException("Invalid day: " + day);
        };

        System.out.println("Day " + day + " is " + dayName);
    }
}

3. yield๋ฅผ ์‚ฌ์šฉํ•œ switch ํ‘œํ˜„์‹

public class YieldInSwitchExample {
    public static void main(String[] args) {
        int score = 85;

        // Java 13์˜ switch ํ‘œํ˜„์‹์—์„œ yield ์‚ฌ์šฉ
        String grade = switch (score / 10) {
            case 10, 9 -> "A";
            case 8 -> "B";
            case 7 -> "C";
            case 6 -> "D";
            default -> {
                // ์—ฌ๋Ÿฌ ์ค„์˜ ๋ณต์žกํ•œ ๋กœ์ง์ด ์žˆ์„ ๋•Œ yield ์‚ฌ์šฉ ๊ฐ€๋Šฅ
                System.out.println("Failing grade.");
                yield "F";
            }
        };

        System.out.println("Grade: " + grade);  // ์ถœ๋ ฅ: Grade: B
    }
}

4. ZGC (Z Garbage Collector) ๊ฐœ์„ 
5. ํž™ ์˜์—ญ ํ™•์žฅ (Dynamic CDS Archives)

Java 14 (2020๋…„ ์ถœ์‹œ)

Java 14๋Š” ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ์„ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ํฅ๋ฏธ๋กœ์šด ๊ธฐ๋Šฅ์„ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • Pattern Matching for instanceof (๋ฏธ๋ฆฌ๋ณด๊ธฐ): instanceof์™€ ํƒ€์ž… ์บ์ŠคํŒ…์„ ๊ฒฐํ•ฉํ•˜์—ฌ ์ฝ”๋“œ ๊ฐ„์†Œํ™”.
  • Record ํƒ€์ž… (๋ฏธ๋ฆฌ๋ณด๊ธฐ): ๋ถˆ๋ณ€ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” Record ํƒ€์ž… ์ถ”๊ฐ€.
  • NPE ๊ฐœ์„ : NullPointerException ๋ฐœ์ƒ ์‹œ ๋” ๊ตฌ์ฒด์ ์ธ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋„๋ก ๊ฐœ์„ .

 

1. switch ํ‘œํ˜„์‹์˜ ๊ฐœ์„  (Switch Expressions) - ์ •์‹ ๋„์ž…

- switch ํ‘œํ˜„์‹์ด ์ •์‹ ๊ธฐ๋Šฅ์œผ๋กœ ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ yield๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ธฐ์กด์˜ switch ๋ฌธ๋ณด๋‹ค ๊ฐ„๊ฒฐํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2. NullPointerException์˜ ์ƒ์„ธ ๋ฉ”์‹œ์ง€ ๊ฐœ์„ 

- NullPointerException์˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋” ์ƒ์„ธํ•˜๊ฒŒ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์–ด๋””์—์„œ null์ด ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์ •ํ™•ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3. ๋ ˆ์ฝ”๋“œ (Records) - ํ”„๋ฆฌ๋ทฐ ๊ธฐ๋Šฅ

// ๋ ˆ์ฝ”๋“œ ์ •์˜
public record Person(String name, int age) {}

public class RecordExample {
    public static void main(String[] args) {
        // ๋ ˆ์ฝ”๋“œ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
        Person person = new Person("John", 25);

        // ์ž๋™ ์ƒ์„ฑ๋œ ๋ฉ”์†Œ๋“œ ์‚ฌ์šฉ
        System.out.println(person.name());  // ์ถœ๋ ฅ: John
        System.out.println(person.age());   // ์ถœ๋ ฅ: 25
        System.out.println(person);         // ์ถœ๋ ฅ: Person[name=John, age=25]
    }
}

4. ํŒจํ„ด ๋งค์นญ์„ ์ด์šฉํ•œ instanceof

- instanceof ๊ตฌ๋ฌธ์—์„œ ํƒ€์ž… ์บ์ŠคํŒ…์„ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” ํŒจํ„ด ๋งค์นญ ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ instanceof๋กœ ํƒ€์ž…์„ ํ™•์ธํ•œ ํ›„, ๋ฐ”๋กœ ํ•ด๋‹น ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

public class InstanceofPatternMatchingExample {
    public static void main(String[] args) {
        Object obj = "Hello, Java 14!";

        // ํŒจํ„ด ๋งค์นญ์„ ์‚ฌ์šฉํ•œ instanceof
        if (obj instanceof String s) {
            System.out.println(s.toUpperCase());  // ์ถœ๋ ฅ: HELLO, JAVA 14!
        }
    }
}

5. helpful NullPointerExceptions ์˜ต์…˜

- NullPointerException์— ๋Œ€ํ•œ ์œ ์šฉํ•œ ์ •๋ณด๊ฐ€ ํฌํ•จ๋œ ์ƒ์„ธ ๋ฉ”์‹œ์ง€๋ฅผ ์ œ๊ณตํ•˜๋Š” helpful NullPointerExceptions ์˜ต์…˜์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋””๋ฒ„๊น…์ด ํ›จ์”ฌ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค. JVM์„ ์‹คํ–‰ํ•  ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

java -XX:+ShowCodeDetailsInExceptionMessages MyApp.jar

6. JEP 367: ZGC on macOS and Windows

- ZGC(Z Garbage Collector)๊ฐ€ macOS์™€ Windows์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ZGC๋Š” ๋งค์šฐ ์งง์€ ์ง€์—ฐ ์‹œ๊ฐ„์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ์ž…๋‹ˆ๋‹ค. ์˜ˆ์ œ ์ฝ”๋“œ๋กœ๋Š” ์ง์ ‘ ํ™•์ธํ•˜๊ธฐ ์–ด๋ ต์ง€๋งŒ, ZGC๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค

java -XX:+UseZGC -Xmx4g -Xms4g MyApp.jar

Java 15 (2020๋…„ ์ถœ์‹œ)

Java 15๋Š” ์—ฌ๋Ÿฌ ์‹คํ—˜์  ๊ธฐ๋Šฅ๋“ค์„ ์™„์„ฑ์‹œํ‚ค๋Š” ์ค‘์š”ํ•œ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค.

  • ํ…์ŠคํŠธ ๋ธ”๋ก (Text Blocks, ์ •์‹): ์—ฌ๋Ÿฌ ์ค„ ๋ฌธ์ž์—ด์„ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์ •์‹์œผ๋กœ ๋„์ž…๋จ.
  • Sealed ํด๋ž˜์Šค (๋ฏธ๋ฆฌ๋ณด๊ธฐ): ํด๋ž˜์Šค ๊ณ„์ธต์„ ์ œํ•œํ•˜๋Š” ๊ธฐ๋Šฅ์œผ๋กœ, ํŠน์ • ํด๋ž˜์Šค๋งŒ ์ƒ์†ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉ.
  • Hidden ํด๋ž˜์Šค: ๋Ÿฐํƒ€์ž„์—์„œ ์ƒ์„ฑ๋˜๊ณ  ์ดํ›„ ๋‹ค์‹œ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ํด๋ž˜์Šค๋“ค์„ ์œ„ํ•œ ๊ธฐ๋Šฅ.

1. ๋ ˆ์ฝ”๋“œ (Records) - ๊ฐœ์„ 

2. Sealed Classes (๋ด‰์ธ๋œ ํด๋ž˜์Šค) - ํ”„๋ฆฌ๋ทฐ ๊ธฐ๋Šฅ

// ๋ด‰์ธ๋œ ํด๋ž˜์Šค ์ •์˜
public sealed class Shape permits Circle, Square {}

final class Circle extends Shape {
    double radius;
}

final class Square extends Shape {
    double side;
}

public class SealedClassExample {
    public static void main(String[] args) {
        Shape shape1 = new Circle();
        Shape shape2 = new Square();
        System.out.println("Shape1 is a " + shape1.getClass().getSimpleName());
        System.out.println("Shape2 is a " + shape2.getClass().getSimpleName());
    }
}

3. ํ…์ŠคํŠธ ๋ธ”๋ก (Text Blocks) - ์ •์‹ ๋„์ž…

4. ํŒจํ„ด ๋งค์นญ์„ ์ด์šฉํ•œ instanceof์˜ ๊ฐœ์„ 

5. ์ˆจ๊ฒจ์ง„ ํด๋ž˜์Šค (Hidden Classes)

- **์ˆจ๊ฒจ์ง„ ํด๋ž˜์Šค (Hidden Classes)**๋ผ๋Š” ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค๋Š” ๋Ÿฐํƒ€์ž„์—๋งŒ ์‚ฌ์šฉ๋˜๊ณ , ์ง์ ‘์ ์œผ๋กœ ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋Š” ํด๋ž˜์Šค๋กœ, ์ฃผ๋กœ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋™์ ์œผ๋กœ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ ์ฝ”๋“œ๋กœ๋Š” ๋‹ค์†Œ ๋ณต์žกํ•˜๋ฉฐ, ํ”„๋ ˆ์ž„์›Œํฌ ์ˆ˜์ค€์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

Java 16 (2021๋…„ ์ถœ์‹œ)

Java 16์€ ์„ฑ๋Šฅ๊ณผ ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ์— ์ดˆ์ ์„ ๋งž์ท„์Šต๋‹ˆ๋‹ค.

  • Record (์ •์‹): Record ํƒ€์ž…์ด ์ •์‹ ๊ธฐ๋Šฅ์œผ๋กœ ๋„์ž…๋˜์–ด ๋ถˆ๋ณ€ ๊ฐ์ฒด์˜ ์„ ์–ธ์ด ๊ฐ„์†Œํ™”๋จ.
  • ํŒจํ„ด ๋งค์นญ for instanceof (์ •์‹): instanceof์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํŒจํ„ด ๋งค์นญ์ด ์ •์‹์œผ๋กœ ๋„์ž…๋จ.
  • Stream.toList(): ์ŠคํŠธ๋ฆผ์„ ๋ฆฌ์ŠคํŠธ๋กœ ์‰ฝ๊ฒŒ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€.

1. ๋ ˆ์ฝ”๋“œ (Records) - ์ •์‹ ๊ธฐ๋Šฅ

2. ํŒจํ„ด ๋งค์นญ์„ ์ด์šฉํ•œ instanceof - ์ •์‹ ๋„์ž…

3. Stream API ๊ฐœ์„ 

4. ํ”„๋ก์‹œ์˜ ์ง๋ ฌํ™” ๊ธฐ๋Šฅ ๊ฐœ์„ 

5. Vector API (Incubator)

public class VectorAPIExample {
    public static void main(String[] args) {
        // Int ๋ฒกํ„ฐ ์—ฐ์‚ฐ ์˜ˆ์ œ
        VectorSpecies<Integer> SPECIES = IntVector.SPECIES_256;
        int[] a = {1, 2, 3, 4, 5, 6, 7, 8};
        int[] b = {1, 2, 3, 4, 5, 6, 7, 8};
        int[] c = new int[8];

        var av = IntVector.fromArray(SPECIES, a, 0);
        var bv = IntVector.fromArray(SPECIES, b, 0);
        var cv = av.add(bv);
        cv.intoArray(c, 0);

        for (int value : c) {
            System.out.println(value);  // ์ถœ๋ ฅ: 2 4 6 8 10 12 14 16
        }
    }
}

6. Sealed Classes (๋ด‰์ธ๋œ ํด๋ž˜์Šค) - ํ”„๋ฆฌ๋ทฐ ๊ธฐ๋Šฅ (๊ณ„์† ๊ฐœ์„ )

 

Java 17 (2021๋…„ ์ถœ์‹œ, LTS)

Java 17์€ Java 11 ์ดํ›„์˜ ๋‘ ๋ฒˆ์งธ ์žฅ๊ธฐ ์ง€์›(LTS) ๋ฒ„์ „์œผ๋กœ, ๋งŽ์€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๊ณผ ์•ˆ์ •์„ฑ ๊ฐœ์„ ์ด ํฌํ•จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

  • Sealed ํด๋ž˜์Šค (์ •์‹): ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ์ œํ•œํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์ •์‹์œผ๋กœ ๋„์ž…๋จ.
  • Pattern Matching for switch (๋ฏธ๋ฆฌ๋ณด๊ธฐ): switch ๋ฌธ์—์„œ ํŒจํ„ด ๋งค์นญ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.
  • Foreign Function & Memory API (๋ฏธ๋ฆฌ๋ณด๊ธฐ): ์™ธ๋ถ€ ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ๊ณผ ์™ธ๋ถ€ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ๋ณด๋‹ค ํšจ์œจ์ ์œผ๋กœ ํ•  ์ˆ˜ ์žˆ๋Š” API ์ถ”๊ฐ€.

1. ํŒจํ„ด ๋งค์นญ์„ ์ด์šฉํ•œ switch ํ‘œํ˜„์‹

public class PatternMatchingSwitchExample {
    public static void main(String[] args) {
        Object obj = "Hello, Java 17!";

        // ํŒจํ„ด ๋งค์นญ์„ ์ด์šฉํ•œ switch ํ‘œํ˜„์‹
        String result = switch (obj) {
            case Integer i -> "Integer: " + i;
            case String s -> "String: " + s;
            case null -> "Null value";
            default -> "Unknown type";
        };

        System.out.println(result);  // ์ถœ๋ ฅ: String: Hello, Java 17!
    }
}

2. ๋ ˆ์ฝ”๋“œ (Records)์™€ Sealed Classes์˜ ์กฐํ•ฉ

public sealed interface Shape permits Circle, Rectangle {}

public record Circle(double radius) implements Shape {}

public record Rectangle(double width, double height) implements Shape {}

public class SealedRecordExample {
    public static void main(String[] args) {
        Shape shape = new Circle(5.0);

        String description = switch (shape) {
            case Circle c -> "Circle with radius: " + c.radius();
            case Rectangle r -> "Rectangle with width: " + r.width() + " and height: " + r.height();
        };

        System.out.println(description);  // ์ถœ๋ ฅ: Circle with radius: 5.0
    }
}

3. ๊ฐ•๋ ฅํ•œ Random๊ตฌํ˜„

public class RandomExample {
    public static void main(String[] args) {
        // RandomGenerator ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ด์šฉํ•œ ๋žœ๋ค ์ˆซ์ž ์ƒ์„ฑ๊ธฐ
        RandomGenerator generator = RandomGeneratorFactory.of("Xoshiro256PlusPlus").create();

        for (int i = 0; i < 5; i++) {
            System.out.println(generator.nextInt(100));  // 0๋ถ€ํ„ฐ 100 ์‚ฌ์ด์˜ ๋‚œ์ˆ˜ ์ถœ๋ ฅ
        }
    }
}

Java 18 (2022๋…„ ์ถœ์‹œ)

Java 18์€ ์ฃผ๋กœ ์„ฑ๋Šฅ๊ณผ ๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜ ํ–ฅ์ƒ์— ์ดˆ์ ์„ ๋งž์ถ˜ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค.

  • Simple Web Server: ๊ฐ„๋‹จํ•œ ๊ฐœ๋ฐœ ๋ฐ ํ…Œ์ŠคํŠธ์šฉ ์›น ์„œ๋ฒ„ ์ถ”๊ฐ€.
  • UTF-8 ๊ธฐ๋ณธ ๋ฌธ์ž ์ธ์ฝ”๋”ฉ: ๋ชจ๋“  ํ”Œ๋žซํผ์—์„œ UTF-8์„ ๊ธฐ๋ณธ ์ธ์ฝ”๋”ฉ์œผ๋กœ ์‚ฌ์šฉํ•˜๋„๋ก ํ‘œ์ค€ํ™”.

1. Simple Web Server

public class SimpleWebServerExample {
    public static void main(String[] args) throws IOException {
        // HTTP ์„œ๋ฒ„ ์ƒ์„ฑ
        HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);

        // ์š”์ฒญ์— ๋Œ€ํ•ด ๊ฐ„๋‹จํ•œ ์‘๋‹ต ์ž‘์„ฑ
        server.createContext("/", exchange -> {
            String response = "Hello, Java 18!";
            exchange.sendResponseHeaders(200, response.getBytes().length);
            exchange.getResponseBody().write(response.getBytes());
            exchange.close();
        });

        // ์„œ๋ฒ„ ์‹œ์ž‘
        server.start();
        System.out.println("Server started at http://localhost:8080");
    }
}

2. Code Snippets in JavaDoc (JEP 413)

/**
 * ์ด ํด๋ž˜์Šค๋Š” Java 18์˜ JavaDoc ์ฝ”๋“œ ์Šค๋‹ˆํŽซ ๊ธฐ๋Šฅ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
 * {@snippet :
 *  // JavaDoc์— ์ฝ”๋“œ ์˜ˆ์‹œ ์‚ฝ์ž…
 *  System.out.println("Hello, JavaDoc Snippets!");
 * }
 */
public class JavadocSnippetExample {
    public static void main(String[] args) {
        System.out.println("Hello, Java 18!");
    }
}

Java 19 (2022๋…„ ์ถœ์‹œ)

Java 19๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์‹คํ—˜์ ์œผ๋กœ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • Virtual Threads (๋ฏธ๋ฆฌ๋ณด๊ธฐ): Java์˜ ๋™์‹œ์„ฑ ๋ชจ๋ธ์„ ๊ฐœ์„ ํ•˜์—ฌ ๋” ๋งŽ์€ ์Šค๋ ˆ๋“œ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›.
  • Structured Concurrency (๋ฏธ๋ฆฌ๋ณด๊ธฐ): ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ ์ž‘์—…์„ ๊ตฌ์กฐํ™”ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•˜๋Š” API.

Java 20 (2023๋…„ ์ถœ์‹œ)

Java 20์—์„œ๋Š” ์ฃผ๋กœ ์ด์ „์— ๋„์ž…๋œ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๊ฑฐ๋‚˜ ์‹คํ—˜์  ๊ธฐ๋Šฅ๋“ค์„ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • Virtual Threads (ํ™•์žฅ๋œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ): ๊ฐ€๋ฒผ์šด ์Šค๋ ˆ๋“œ๋กœ ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ฐ ๊ฐœ์„ .
  • Pattern Matching for switch (ํ™•์žฅ๋œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ): switch ๋ฌธ์—์„œ ๋” ๊ฐ•๋ ฅํ•œ ํŒจํ„ด ๋งค์นญ ๊ฐ€๋Šฅ.

Java 21 (2023๋…„ ์ถœ์‹œ, LTS)

Java 21์€ ์ƒˆ๋กœ์šด LTS ๋ฒ„์ „์œผ๋กœ ์žฅ๊ธฐ์ ์œผ๋กœ ์ง€์›๋˜๋ฉฐ, ๋งŽ์€ ์ฃผ์š” ๊ธฐ๋Šฅ์„ ์ •์‹์œผ๋กœ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • Virtual Threads (์ •์‹): ๋™์‹œ์„ฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ๊ฐ€๋ฒผ์šด ์Šค๋ ˆ๋“œ ๊ธฐ๋Šฅ์ด ์ •์‹์œผ๋กœ ์ถ”๊ฐ€๋จ.
  • Pattern Matching for switch (์ •์‹): switch ๋ฌธ์—์„œ ๋” ๋ณต์žกํ•œ ํŒจํ„ด ๋งค์นญ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋˜์—ˆ์Œ.
  • Record Patterns (์ •์‹): record์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํŒจํ„ด ๋งค์นญ ์ง€์›.
  • Sequenced Collections: ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜๋Š” ์ƒˆ๋กœ์šด ์ปฌ๋ ‰์…˜ ์ธํ„ฐํŽ˜์ด์Šค ๋„์ž….

1. Virtual Threads (๊ฐ€์ƒ ์Šค๋ ˆ๋“œ) - ์ •์‹ ๊ธฐ๋Šฅ

public class VirtualThreadExample {
    public static void main(String[] args) throws InterruptedException {
        // ๊ฐ€์ƒ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ExecutorService ์ƒ์„ฑ
        try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
            for (int i = 0; i < 10; i++) {
                executor.submit(() -> {
                    System.out.println("Running on virtual thread: " + Thread.currentThread());
                });
            }
        }
    }
}

2. Pattern Matching for switch - ์ •์‹ ๊ธฐ๋Šฅ

public class PatternMatchingSwitchExample {
    public static void main(String[] args) {
        Object obj = "Java 21";

        // ํŒจํ„ด ๋งค์นญ์„ ์‚ฌ์šฉํ•˜๋Š” switch ํ‘œํ˜„์‹
        String result = switch (obj) {
            case Integer i -> "Integer: " + i;
            case String s -> "String: " + s.toUpperCase();
            case null -> "Null value";
            default -> "Unknown type";
        };

        System.out.println(result);  // ์ถœ๋ ฅ: String: JAVA 21
    }
}

3. Sequenced Collections

public class SequencedCollectionExample {
    public static void main(String[] args) {
        SequencedCollection<String> sequencedList = new LinkedList<>();
        sequencedList.addFirst("First");
        sequencedList.addLast("Last");

        System.out.println("First element: " + sequencedList.getFirst());
        System.out.println("Last element: " + sequencedList.getLast());
    }
}

4. String Templates - ํ”„๋ฆฌ๋ทฐ ๊ธฐ๋Šฅ

public class StringTemplateExample {
    public static void main(String[] args) {
        int age = 25;
        String name = "Alice";

        // ๋ฌธ์ž์—ด ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•œ ๊ฐ„๊ฒฐํ•œ ํ‘œํ˜„
        String result = STR."Hello, \{name}! You are \{age} years old.";
        System.out.println(result);  // ์ถœ๋ ฅ: Hello, Alice! You are 25 years old.
    }
}

5. Unnamed Classes and Instance Main Methods - ํ”„๋ฆฌ๋ทฐ ๊ธฐ๋Šฅ

public class MainExample {
    void main() {
        System.out.println("Instance Main Method");
    }

    public static void main(String[] args) {
        new MainExample().main();  // ์ถœ๋ ฅ: Instance Main Method
    }
}

6. Foreign Function & Memory API - ์ •์‹ ๊ธฐ๋Šฅ

public class ForeignFunctionMemoryExample {
    public static void main(String[] args) {
        try (MemorySegment segment = MemorySegment.allocateNative(JAVA_INT)) {
            segment.set(JAVA_INT, 0, 42);
            int value = segment.get(JAVA_INT, 0);
            System.out.println("Value from native memory: " + value);  // ์ถœ๋ ฅ: 42
        }
    }
}

 

๊ฒฐ๋ก 

  • Java 8: ๋žŒ๋‹ค, ์ŠคํŠธ๋ฆผ API, ์ƒˆ๋กœ์šด ๋‚ ์งœ ๋ฐ ์‹œ๊ฐ„ API ๋“ฑ.
  • Java 9~10: ๋ชจ๋“ˆ ์‹œ์Šคํ…œ๊ณผ var ํƒ€์ž… ์ถ”๋ก  ๋“ฑ.
  • Java 11: LTS ๋ฒ„์ „์œผ๋กœ HTTP ํด๋ผ์ด์–ธํŠธ API์™€ ์ƒˆ๋กœ์šด String ๋ฉ”์„œ๋“œ.
  • Java 12~15: Switch ํ‘œํ˜„์‹, ํ…์ŠคํŠธ ๋ธ”๋ก, ํŒจํ„ด ๋งค์นญ ๋“ฑ์˜ ์‹คํ—˜์  ๊ธฐ๋Šฅ.
  • Java 16~17: Record์™€ Sealed ํด๋ž˜์Šค ์ •์‹ ๋„์ž…, ํŒจํ„ด ๋งค์นญ ๊ธฐ๋Šฅ ๊ฐ•ํ™”.
  • Java 18~21: Virtual Threads, Pattern Matching for switch ๋“ฑ์˜ ๋™์‹œ์„ฑ ๋ฐ ํŒจํ„ด ๋งค์นญ ๊ธฐ๋Šฅ ๊ฐœ์„ .

๊ฐ ๋ฒ„์ „๋งˆ๋‹ค Java ์–ธ์–ด์™€ ๋Ÿฐํƒ€์ž„์— ์ค‘์š”ํ•œ ๊ฐœ์„  ์‚ฌํ•ญ๋“ค์ด ๋„์ž…๋˜์—ˆ์œผ๋ฉฐ, ํŠนํžˆ Java 8, 11, 17, 21์€ LTS ๋ฒ„์ „์œผ๋กœ ์žฅ๊ธฐ์ ์ธ ์ง€์›์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

'๐Ÿ“บ Develop > โœ๏ธ JAVA' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

JAVA (JDK, JRE, JVM ์ฐจ์ด์ )  (0) 2024.10.18
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
ยซ   2024/12   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
๊ธ€ ๋ณด๊ด€ํ•จ
๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (80)
๐Ÿ“บ Develop (0)
๐ŸŒ‹ Error Fixed (5)
๐Ÿ— Tool (5)
๐Ÿ’ป MacBook M1 (15)
๐Ÿ“ฆ ETC (1)

์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค.