개발언어/JAVA

Java 9 ~ 17까지 도입할만한 유용한 기능과 예시

nomoreFt 2023. 7. 20. 16:32

Java 9

  • 인터페이스의 private 메소드: 인터페이스에서도 private 메소드를 선언할 수 있게 되었습니다. 이를 통해 코드의 재사용성을 높일 수 있습니다.
    • 메소드 구현의 세부 사항 숨기기: private 메소드는 인터페이스 외부에서는 접근할 수 없으므로, 메소드의 구현 세부 사항을 숨기고 추상화 수준을 높일 수 있습니다. 이는 캡슐화 원칙을 더 잘 지키는 데 도움이 됩니다.
    • 인터페이스의 안정성 향상: private 메소드는 인터페이스의 공개 API의 일부가 아니므로, 이를 변경하더라도 인터페이스를 구현하는 클래스들에게 영향을 미치지 않습니다. 따라서 인터페이스의 안정성을 향상시키는 데 도움이 됩니다.
public interface MyInterface {
    default void myMethod() {
        helperMethod();
    }

    private void helperMethod() {
        System.out.println("Helper method in interface");
    }
}

Java 10

  • 지역 변수의 타입 추론(var): 자료형을 명시하지 않아도, 컴파일러가 변수의 타입을 추론할 수 있게 해줍니다.
// Old way
String name = "John";

// New way
var name = "John";

Java 11

  • String의 새로운 메소드들: String 클래스에는 isBlank(), lines(), strip(), repeat() 등 새로운 메소드들이 추가되었습니다.
var name = "  John  ";

// Using new methods
System.out.println(name.isBlank());       // false
System.out.println(name.strip());         // "John"
System.out.println(name.repeat(2));       // "  John    John  "
  • Predicate.not 이 생겼습니다. filter시에 부정문으로 제끼기 더 편해졌네요.
List<String> myList = Arrays.asList("Like,"  ", "Subscribe");
List<String> withoutBlanks = myList.stream()
                            .filter(Predicate.not(String::isBlank))
                            .collect(Collectors.toList());
  • toArray 메서드가 생겼습니다.

List<String> list = Arrays.asList("Like","and","Piece");
String[] array = list.toArray(String[]::new);
  • List의 CopyOf, Collectors.toUnmodifiableList 메서드가 생겼습니다.
List<String> modifiableList = new ArrayList<>();
modifiableList.add("foo");
modifiableList.add("bar");

List<String> unmodifiableList = List.copyOf(modifiableList);

// 이 코드는 UnsupportedOperationException을 던집니다.
unmodifiableList.add("baz");


---------------------------------------------------

List<String> list = Stream.of("apple", "banana", "cherry")
                                  .collect(Collectors.toUnmodifiableList());

System.out.println(list);

// UnsupportedOperationException을 발생시킵니다.
list.add("orange");

  • 불변 리스트의 장점
    • 외부 코드에 리스트를 전달할 때: unmodifiableList를 사용하면 외부 코드가 리스트를 변경하는 것을 막을 수 있습니다.
    • 멀티스레드 환경에서 리스트를 공유할 때: unmodifiableList를 사용하면 여러 스레드가 동시에 리스트를 변경하는 것을 방지할 수 있습니다.
  • writeStirng , readString File을 String으로 처리할 수 있게 되었습니다.
String file = "java11.txt"
Files.writeString(Paths.get(file), "Geekific", StandardOpenOption.CREATE);
String content = Files.readString(Paths.get(file));
System.out.println(content);

Java 12

  • Switch Expressions: switch 문이 표현식으로 사용될 수 있게 되었으며, yield 키워드를 사용하여 값을 반환할 수 있게 되었습니다.
// Old way
String day = "MONDAY";
switch (day) {
    case "MONDAY":
        System.out.println("It's Monday");
        break;
    // ... and so on
}

// New way
String day = "MONDAY";
switch (day) {
    case "MONDAY" -> System.out.println("It's Monday");
    // ... and so on
}

Java 13

  • 텍스트 블록(Text Blocks): 세 개의 큰 따옴표(""")를 사용하여 멀티 라인 문자열을 표현할 수 있게 되었습니다.

String text = """
              Hello,
              World
              """;

Java 14

  • instanceof 패턴 매칭: instanceof 연산자가 패턴 매칭을 지원하게 되어, 캐스팅 없이 조건문을 사용할 수 있게 되었습니다.

//이전
Person person = new Employee();
if(person instanceof Employee) {
    Employee employee = (Employee) person;
    //형변환 하고 할일 진행
}

//발전

if(person instanceof Employee employee && employee.getYearsOfService() > 5){
//    employee로 바로 Employee 할 일 진행
}

Java 15

  • Sealed Classes: 클래스 또는 인터페이스를 특정 타입들에게만 상속 또는 구현을 허용하도록 제한할 수 있게 되었습니다.
public sealed interface Shape permits Circle, Rectangle {
    // ...
}

public final class Circle implements Shape {
    // ...
}

public non-sealed class Rectangle implements Shape {
    // ...
}

Java 16

  • Records: 클래스의 필드, 생성자, getter, equals(), hashCode(), toString() 등을 자동으로 생성해주는 기능입니다. DTO 나 OpenAPI에서 받아오는 Response 객체 등을 담을 때 유용할 것 같습니다.
record Point(int x, int y) { }

Java 17

  • String indent 메서드. 들여쓰기가 편해집니다.
String text = "test!!!!"
text = text.indent(4); // "    test!!!!"
text = text.indent(-2); // "  test!!!!"
  • String transform 메서드. 파라미터 자를때 유용하게 쓸 수 있을 것 같습니다.
"test!@#$".transform(value ->
            new StringBuilder(value).delete(4,7).toString());

            //test 반환
  • Collectors.teeing 메서드
public static <T,A1,R1,A2,R2,R> Collector<T,?,R> teeing(
    Collector<? super T,A1,R1> downstream1,
    Collector<? super T,A2,R2> downstream2,
    BiFunction<? super R1,? super R2,R> merger
)
* downstream1과 downstream2는 두 개의 다운스트림 컬렉터입니다.
* merger는 두 다운스트림 결과를 결합하는 함수입니다.
사용 예시

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        Integer range = numbers.stream()
                .collect(Collectors.teeing(
                        Collectors.minBy(Integer::compareTo),
                        Collectors.maxBy(Integer::compareTo),
                        (min, max) -> max.orElse(0) - min.orElse(0)
                ));

        System.out.println("Range: " + range);