개요

대부분의 핸드폰과 같은 물건들은 기존에 사용하던 것들의 단점을 보완하며 추가적인 기능을 부여하기 위해 항상 발전을 해왔습니다. 핸드폰을 예시로 들면 문자와 전화통신, 이미지첨부등의 간단한 기능만 있던것이 이동통신망을 구축하고 무선 인터넷이 추가되어 핸드폰으로 인터넷을 탐색하며, 그 사물에 대한 단점들을 보완하기위해 새로운 버전의 핸드폰들이 개발되어 나옵니다.

프로그래밍 언어 또한 이와비슷합니다.

기존의 자바 초기버전에서 각각의 단점들을 보완하며, 새로운 기능들을 추가해 왔습니다.

하지만, 저희가 항상 새로운 물건을 살 수 없듯이, 프로그래밍 환경에서도 항상 새로운 버전으로 교체하여 사용할 수없습니다. 만약에 기존의 학습용으로 사용하던 버전이 업무시의 버전보다 높다면, 어떤 기능이 사라져있는지를 인지해야합니다.

이러한 이유로 이번 포스팅에서는 자바8에서 추가된 기능들과 자바 11에서 추가된 기능 등에 대해 알아보겠습니다.

 

Java8에서 추가된 기능

Java8에서 추가된 기능들은 Lambda 표현식, 함수형 인터페이스, Stream, Optional, 인터페이스의 기본 메서드,

날짜 관련 클래스, 병렬 배열 정렬, StringJoiner등이 있으며 그외에도 다양한 기능들이 추가되었습니다.

그중에 개발자들이 자주 사용할 기능들에 대하여 알아보겠습니다.

 

 1. Lambda (람다 표현식)

람다는 함수를 하나의 표현식으로 나타낸것을 의미합니다.

기존 함수형 프로그래밍 언어에서 사용되었던 기능이며, 익명 클래스와 같이 메서드에 이름이 없습니다.

람다는 일회성으로 사용되며 코드를 간결하게하며 가독성이 뛰어나다는 장점이 있습니다.

하지만 재활용이 불가능 하므로 반복적인 호출이 필요한 경우에는 사용하지 않는것이 좋습니다.

        // 기존 반복문
        for (String str : strList) {
            System.out.println(str);
        }
        
        // 람다 표현식
        strList.forEach(str -> System.out.println(str));

람다 표현식은 기존의 코드를 간결화 시키는 방식으로, 매개 변수 목록, 화살표 토큰, 처리 식으로 구성 할 수있습니다.

 

 

2. Functional Interface(함수형 인터페이스)

함수형 인터페이스는 java.util.function 패키지에 포함되어있으며 각각의 인터페이스에 하나의 추상화된 메서드가 구성되어있습니다. 어노테이션 @FunctionalInterface를 사용하여 함수형 인터페이스라는것을 명시 할 수있습니다.

 

 

3. Stream (스트림)

스트림의 사전적 정의는 개울, 시내 / (액체 기체의) 줄기 / (사람 차량들로 계속 이어진) 줄 이라는 의미가있습니다.

자바언어에서의 스트림도 사전적 의미와 비슷하게 어떠한 연속된 정보를 담고있는 것을 처리하는것을 의미합니다.

연속된 정보들은 하나의 노드가 다음 노드의 주소를 가르킬 수 있는것 들을 말하며 자바에서는 컬렉션과 배열이 있습니다.

스트림의 구조는 연속된요소의 스트림 생성 / 중개 연산 / 종단 연산으로 이루어져 있습니다.

        intList.stream()                // 스트림 생성
                .filter(x -> x>10)      // 중개 연산
                .count();               // 종단 연산

 

스트림 생성 : 컬렉션의 목록을 스트림 객체로 변환한다. stream()메서드를 사용하여 Stream타입을 리턴한다.

중개 연산 : 중개연산은 데이터를 가공할 때 사용하며 연산결과고 Stream 타입을 리턴한다. 따라서 여러개의 중간연산을 연결 할 수 있다. 또한 중개 연산은 0개이상이 존재해야한다. 즉, 생략이 가능하다.

종단 연산 : 중개 연산에서 작업된 내용을 바탕으로 스트림 처리를 마무리 하며, 숫자 혹은 목록형 데이터를 리턴한다.

 

 

4. Method Reference (메서드 참조)

메서드 참조는 람다식이나 스트림을 더 간결하게 사용하기위해 더블 콜론 " :: " 을 사용하는 것을 의미합니다.

메서드 참조의 종류에는 정적 메서드 참조, 인스턴스 메서드 참조, 생성자 참조, 특정유형의 객체에 대한 인스턴스 메서드참조가 있습니다. 

    // 정적 메서드 선언
    private static void printResult(String value)
    {
        System.out.println(value);
    }
    // 정적 메서드 참조 
    public void staticReference(String[] stringArray)
    {
        Stream.of(stringArray).forEach(Lambda::printResult);
    }
    
    // 인스턴스 메서드 참조 
    public void instanceMethod()
    {
        intList.stream().forEach(System.out::println);
    }
    
    // 특정 유형의 임의의 객체에 대한 인스턴스 메서드 참조
    public void objectReference(String[] stringArray)
    {
        Arrays.sort(stringArray, String::compareToIgnoreCase);              // 임의 객체 참조
        Arrays.asList(stringArray).stream().forEach(System.out::println);   //인스턴스 메서드 참조
    }
    
    //생성자 참조
    interface MakeString                
    {
        String fromBytes(char[] chars);         // char[] 배열을 받는 메서드 선언.
    }
    public void createInstance()
    {
        MakeString makeString = String::new;    // String 생성자(char[]을 받아오는) 생성.   
    }

 

 

5.Optional 

Optional은 함수형 언어인 Haskell과 Scala에서 제공하는 기능을 Java8에서 사용할 수 있게 만든 클래스 입니다.

해당 클래스는 final 클래스로 선언되어 있으며, 객체를 생성하지 않아도 사용할 수 있습니다.

Optional클래스는 NullPointerException의 예외가 발생할 경우에 안정성과 더 간결하게 사용하기 위해 만들어둔 클래스입니다.

 

 

6.날짜 관련 클래스

Java8의 이전에서는 Data나 SimpleDataFormatter클래스를 사용하여 시간을 처리해 왔습니다.

하지만, Thread Safe하지않으며 연산시 객체 자체가 변경되는 경우가 있었습니다.

이러한 문제들을 보완하기위해 Java8에서 ThreadSafe한 클래스와 불변의 객체들로 이루어진 클래스들이 추가되었습니다.

또한 Calendar클래스의 각 타입들은 Int형이였지만, 추가된 클래스에서는 Enum타입이 추가되었습니다.

 

7.CompletableFuture

자바8 이전의 버전에서는 비동기방식의 프로그래밍은 Future 인터페이스를 사용할 수 있었습니다.

Future 인터페이스는 메서드를 통하여 해당 연산의 작업이 완료되었는지, 완료가 될때까지 대기, 완료 후의 결과를 조회하는 기능을 제공하는 블로킹을 해주는 역할을 담당하였습니다.

하지만, Future는 기본적인 기능만을 담당하며, 다른 복잡한 로직에 대해서는 사용하기 힘든 단점 등이 있었습니다.

이를 보완하여 자바8버전에서 CompletableFuture 클래스가 추가되었습니다.

CompletableFuture클래스에서는 기존의 블로킹 방식을 최소화하며, 작업을 완료시 thenApply,thenAccept 메서드 등을 사용한 콜백 기능 추가, 그리고 completeOnTimeout,cancle메서드 등을 사용한 타임아웃 및 취소 등의 기능이 추가되었습니다.

 

이외에도 Java8에서 다양한 기능들이 포함되어있지만, 추가적인 기능들 중 자주 사용하는 기능들에 대하여 알아보았습니다.

 

 

 

Java11에서 추가된 기능

1.Lambda 매개변수에 대한 로컬 변수 Var

지역 변수와의 일관성을 위해 임시적으로 유형이 지정된 람다 식의 매개 변수를 선언할 때 var를 사용할 수있습니다.

지금까지는 변수의 타입을 명시적으로 선언해야 했지만, var 키워드를 통해 컴파일러가 초기화를 기반으로 변수가 어떤 타입인지 추론을 합니다. 이것을 "타입 추론 (Type Inference)" 라고 합니다.

       var str = "This type is String";
        var i = 5;
        var i2 = 10;

        //문자열
        if(str instanceof String)
            System.out.println("str 변수의 타입은 String 입니다.");

        //정수형
        i2 += i;
        System.out.println(i2);

        // 기존의 타입 및 명시적인 선언
        // Before
        List<String> varnames = new ArrayList<>();

        // var을 사용한 타입 추론
        // After
        var varnaems = new ArrayList<String>();

var 키워드는 지역 변수의 타입을 추론할때 사용할 수 있으며, 초기화를 하면서 어떤 타입인지 추론을 하기 때문에

반드시 선언 및 초기화를 동시에 사용해야합니다.

 

 

2. String 클래스의 메서드 추가

String클래스 내에서 isBlank, lines, strip, repeat 등의 메서드들이 추가되었습니다.

        //lines
        String exString = "This is default String";
        System.out.println("Before String : " + exString);
        List<String> lines = new ArrayList<>();
        exString.lines().forEach(lines::add);
        System.out.println("After Line : " + lines);
        
        //Strip
        String stripString = " strip method Test ";
        System.out.println("Before String : " + stripString);
        System.out.println("After String : " + stripString.strip());

        //Repeat
        String beforeRepeat = "ReapetCount";
        String afterRepeat;
        System.out.println("Before String : " + beforeRepeat);
        afterRepeat = beforeRepeat.repeat(3);
        System.out.println("After Repeat String : " + afterRepeat);

        //isBlank
        String blankString = "";
        System.out.println("Blank : " + blankString.isBlank());

String에 추가된 각각의 기능들을 소개하겠습니다.

.lines() : 여러줄 문자열을 줄의 스트림으로 변환한다.

.strip() : 문자열의 시작과 끝부분의 공백(&nbsp)제거한다.

.repeat(index count) : 문자열을 count횟수만큼 반복한다.

.isBlank() : 빈 문자열 및 공백만 있는 문자열인지 Boolean형식으로 반환한다.

 

 

3. File클래스의 메서드 추가

Files클래스 에서 readString writeString의 메서드가 추가되었습니다.

        Path filePath = Path.of("txt url");
        //Read String
        try{
            String readContent = Files.readString(filePath);
            System.out.println(readContent);
        }catch(IOException ioe)
        {
            ioe.printStackTrace();
        }

        //Write String
        try{
            String writeContent = "Write String";
            Files.writeString(filePath, writeContent, StandardOpenOption.CREATE);
        }catch (IOException ioe)
        {
            ioe.printStackTrace();
        }

Files(NIO)클래스에서 해당 readString, writeString메서드들이 추가됨으로써 

문자열들을 읽어오거나, 저장할 시 해당 메서드를 통하여 읽기.쓰기기능을 사용할 수 있습니다. 

 

 

4. 자바 파일 실행

Java11이전의 버전에서는 javac를통해 컴파일을 하였지만, 11이후에서부턴 javac를 통해 컴파일하지않고도 실행이 가능하게 변경되었습니다.

 

 

정리

Java8

  • 람다(Lambda) : 일회성으로 사용되며, 코드 작성시에 보다 간결하게 작성할 수 있다.
  • 함수형 인터페이스(Functional Interface) : 하나의 인터페이스에 하나의 추상 메서드들이 구성되어있다.
  • Stream : 어떠한 연속된 정보들을 담고, 데이터를 가공할수있다. 스트림 생성, 중개연산, 종단연산으로 구성되어있다.
  • 메서드 참조 : (" :: ")을 사용하여 보다 간결하게 구현할 수 있다.
  • Optional : NullPointerException를 보다 안전하게 처리하기 위해 추가된 기능이다.
  • 날짜 관련 클래스 : Java8이후 불변성(변하지않는) 날짜를 쉽게 구현할 수 있게 추가된 기능이다.
  • CompletableFuture : Future인터페이스의 단점들을 보완한 클래스로, 비동기 작업의 연산처리시 사용한다.

Java11

  • Var : 타입 추론을 통해 명시적으로 변수의 타입을 설정하지않아도 컴파일러가 상황에 맞게 타입을 선언한다.
  • Stirng클래스 내의 메서드 추가
  • Files 클래스의 writeString, readString 기능 추가
  • 자바 파일 실행시 javac(자바컴파일러)를 통해 컴파일하지않고 실행을 할 수 있다.

 

느낀점

자바에서도 각각의 기능들이 부족하다고 느끼면 버전업데이트를 하며 동시에 새로운 클래스 추가 또는 메서드들이 추가됐습니다.

이번 포스팅 외에도 다른 기능들이 추가되었지만, 핵심적인 기능만을 작성하였으며 개인 프로젝트 개발시에는 자신이 원하는 자바의 버전을 사용하기때문에 큰 문제점들이 없겠지만, 많은사람들과의 협업 혹은 회사에서의 개발자 근무시에는 해당 언어가 어떤 버전이며, 자신이 다루었던 자바버전에서 어떤 기능들이 제외되었는지, 그리고 그 기능들을 어떻게 구현해야할지 고민할수있엇던 포스팅이였습니다.

 

 

'Java' 카테고리의 다른 글

Exception Handling(회피, 복구, 전환)  (0) 2023.07.26
JVM - Runtime Data Area  (0) 2023.07.06

+ Recent posts