ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 미리보는 java9
    카테고리 없음 2023. 4. 22. 14:40
    오늘은 미리보는 java9의 새로운 기능들을 살펴보자. 물론 지금은 릴리즈전이라 바뀔 내용이 있을 수 있으니 너무 깊게는 살펴보지 말자. 조만간 java9가 릴리즈 될 예정이다. 원래 일정은 올해 초에 릴리즈 될거라고 했었는데 일정이 밀렸다. 왜 밀린지는 모르겠지만.. 아무튼 담달 27일인 7월27일에 다시 릴리즈 예정일이다. 역시 또 밀릴지는 의문이다. (수정) 또 다시 딜레이 되었다고 한다. 릴리즈 일정은 아래와 같다.
    2017/07/06      Final Release Candidate
    2017/09/21      General Availability
    
    그전에 안타까운 소식이 하나 있다. java7부터 언급이 많이 되었던 직소(Jigsaw) 프로젝트가 JCP에 통과하지 못하는 일이 발생하였다. 대부분의 회사들이 반대표를 던졌다. oracle, intel , Azul Systems등이 찬성표를 던졌으나, 이클립스 재단, IBM, 트위터, 레드햇(개빈 킹이겠지?) 등 이 반대표를 던저 23개 회사중 13개의 회사가 반대를 하였다. 그래서 한달이내로 다시 리뷰를 받아야 되는데 해결할 일이 많다고 한다. 그 한달이 거의 다 된거 같은데.. 조만간 소식이 들릴듯 하다. 그래서 여기서는 직소(Jigsaw)는 언급하지 않겠다. 양도 꽤 있어서 만약 java9에 들어간다면 그때 다시..

    Collections 의 팩토리 메서드

    List에는 Arrays 클래스에 존재 했던거지만 List 인터페이스에 새로운 팩토리메서드가 추가로 생겼다.
    List.of(1,2,3,4,5);
    
    위와 같이 간단하게 팩토리 메서드를 호출해서 생성할 수 있다. 메서드 형태들는 다음과 같다.
    static <E> List<E> of(E e1) 
    static <E> List<E> of(E e1, E e2)
    static <E> List<E> of(E e1, E e2, E e3)
    ...
    static <E> List<E> of(E... elements)
    
    List에만 생겼다면 그닥 의미가 별로 없었을 것이다. 하지만 Set, Map에도 추가 되었다.
    Set.of(1,2,3,4,5);
    Map.of("key1", "value1", "key2","value2");
    
    Set의 경우에는 중복을 허용하지 않는다. 그래서 만약 같은 값을 넣을 경우에는 에러를 발생시킨다.
    Set.of(1,2,3,4,1);
    
    ... java.lang.IllegalArgumentException: duplicate element: 1
    ...
    
    또 한 Map도 키는 중복을 허용하지 않는다. 그래서 Set과 마찬가지로 같은 키값을 넣을 경우 에러를 발생시킨다.
    Map.of("key1", "value1", "key1","value2");
    
    참고로 위에 모든 컬렉션은 immutable하다. 변경할 수 없다. 만약 List.of()로 생성하고 add() 메서드를 호출하면 UnsupportedOperationException 이 발생한다. 좀 더 쉽게 Set과 Map을 사용할 수 있어서 괜찮은거 같다.

    Stream API

    Stream에 몇가지 API가 추가 되었다. takeWhile(), dropWhile(), ofNullable()가 추가 되었다.

    takeWhile

    takeWhile() 의 메서드 형태는 다음과 같다.
    default Stream<T> takeWhile(Predicate<? super T> predicate)
    
    이 아이는 특정한 엘리먼트까지 왔다면 멈추고 그 엘리먼트까지 반환한다. Predicate을 파라미터로 받으니 boolean 값을 리턴하면 된다.
    List<Integer> numbers = List.of(1, 3, 7, 8, 15, 4)
            .stream()
            .takeWhile(i -> i < 10)
            .collect(toList());
    
    filter와 유사하다. 하지만 filter와 다른점은 해당 조건까지 왔다면 멈추고 반환한다는 것이다. filter와 비교해보자.
    List<Integer> numbers = List.of(1, 3, 7, 8, 15, 4)
            .stream()
            .filter(i -> i < 10)
            .collect(toList());
    
    filter를 사용했을 경우에는 1, 3, 7, 8, 4를 반환하는 반면에 takeWhile를 사용할 경우에는 1, 3, 7, 8까지 데이터를 반환한다.

    dropWhile

    dropWhile 의 메서드 형태는 다음 과 같다.
    default Stream<T> dropWhile(Predicate<? super T> predicate)
    
    dropWhile() 메서드는 takeWhile() 메서드와 반대 개념이다. takeWhile()메서드가 1, 3, 7, 8를 반환하였다면 dropWhile() 메서드는 나머지인 15, 4를 반환한다.
    List<Integer> numbers = List.of(1, 3, 7, 8, 15, 4)
            .stream()
            .dropWhile(i -> i < 10)
            .collect(toList());
    //[15, 4]
    

    ofNullable

    ofNullable의 메서드 형태는 다음 과 같다.
    public static<T> Stream<T> ofNullable(T t) 
    
    ofNullable() 메서드는 Optional.ofNullable() 과 동일하다. null safe한 메서드 이다.
    Stream.ofNullable(null)
    
    위와 같이 작성해도 에러는 발생하지 않는다.

    Optional API

    Optional에도 몇가지 API가 추가 되었다. stream(), or(), ifPresentOrElse() 메서드가 추가되었다.

    stream

    메서드 명 그대로 Optional을 Stream 타입으로 변경하는 메서드 이다. 메서드 형태는 다음과 같다.
    public Stream<T> stream()
    
    Optional 타입을 만들어서 stream 형태로 만드는 예이다.
    Optional<String> foo = Optional.ofNullable("foo");
    Stream<String> stream = foo.stream();
    

    or

    or 메서드는 기존의 orXXX 와 비슷한 메서드이다. or 메서드 경우에는 Optional을 다시 리턴한다. 메서드 형태는 다음과 같다.
    public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier)
    
    Supplier에 Optional 타입을 받고 Optional을 리턴한다.
    Optional<String> foo = Optional.ofNullable("foo");
    Optional<String> bar = foo.or(() -> Optional.of("bar"));
    // Optional[foo]
    Optional<String> foo = Optional.ofNullable(null);
    Optional<String> bar = foo.or(() -> Optional.of("bar"));
    // Optional[bar]
    

    ifPresentOrElse

    기존의 ifPresent(Consumer<? super T> action) 메서드 형태에서 조금 확장된 형태이다. ifPresent() 메서드 경우에는 값이 있을 경우에만 동작하지만 ifPresentOrElse() 메서드 경우에는 값이 없을 경우에도 동작하는 부분이 추가 되었다. 메서드 형태는 다음과 같다.
    public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)
    
    Runnable을 파라마터로 받는 부분이 추가 되었다.
    Optional<String> foo = Optional.ofNullable("foo");
    foo.ifPresentOrElse(f -> System.out.println(f), () -> System.out.println("bar"));
    // foo
    
    Optional<String> foo = Optional.ofNullable(null);
    foo.ifPresentOrElse(f -> System.out.println(f), () -> System.out.println("bar"));
    // bar 
    

    Process

    ProcessHandle 인터페이스가 추가 되었다. Process관련된 정보들을 쉽게 가져올 수 있다.
    ProcessHandle processHandle = ProcessHandle.current();
    ProcessHandle.Info processInfo = processHandle.info();
    long pid = processHandle.pid();
    System.out.println(pid);
    System.out.println(processInfo.command().get());
    System.out.println(processInfo.startInstant().isPresent());
    System.out.println(processInfo.totalCpuDuration().isPresent());
    
    간단한 인터페이스이기 때문에 한번씩 해보면 될 듯 싶다.

    interface

    우리가 아는 java의 interface를 말하는 거 맞다. java8 부터 인터페이스에 구현을 할 수 있게 된건 누구나 아는 사실이다.
    interface SomeInterface {
        default void doSomething() {
                  System.out.println("blabla");
        }
    }
    
    위와 같이 interface에 default라는 키워드를 사용해서 구현을 할 수 있다. java9 부터는 메서드에 private 접근제한을 둘수 있다.
    interface SomeInterface {
    
        private void doSomething(){
                  System.out.println("blabla");
        }
    }
    
    나쁘지 않다. 하지만 protecteddefault 접근제한은 사용할 수 없다.

    Reactive

    요즘 대두가 많이 되고 있는 Reactive API가 java9에 추가 되었다. 그 구현체 중 Netflix의 rxJava와 Spring의 Reactor 라는 프로젝트가 그 대표적인 예 이다. 자세한 내용은 rxJava와 Reactor라는 프로젝트를 참고하면 되겠다. 필자의 경우에는 Spring을 자주 사용하니 Spring 관련해서 Reactor를 공부할 듯 싶다. Spring5 에서 정식으로 Reactive를 지원하니 Spring5가 나올 때까지 슬슬 공부하면 될 것 같다. Spring boot는 2.0 부터 지원하니 현재 M1 버전으로 공부해도 될 듯 싶다. 그리고 java9가 나오면 java9 쪽으로 인터페이스를 바꾸지 않을까 생각된다. 그냥 필자 생각이지만.. Reactive 또한 이야기 할 것도 많고 쉬운 내용도 아니니 나중에 좀 더 공부를 한뒤에 글을 작성해보도록 하자. 좀 더 많은 내용이 있겠지만 필자가 알아본 정도는 여기까지이다. java9가 릴리즈 되면 차근차근 좀 더 알아볼 수 있도록 하자. 회사에서 사용하려면 좀 더 안정화 되면 사용해야겠지만 개인적으로는 릴리즈 되면 바로 올려서 사용할 예정이다. 직소가 JCP 리뷰에 통과해서 java9에서 만났으면 좋겠다. java7부터 고생이 많다.. 위의 예제들을 간단하게 만들었는데 github에서 살펴보자.

    댓글

Designed by Tistory.