타입 추론

Java 10에서 var라는 Local Variable Type-Inference 가 추가되었다. 그 전에도 Generic 과 Lambda 를 사용할 때 타입 추론이라는 단어를 사용하는 것을 들었다.

타입 추론이란 코드 작성 당시 타입이 정해지지 않았지만, 컴파일러가 그 타입을 유추하는 것이다.

Generic

Lambda

람다란 함수형 인터페이스를 통해 bolierplate 코드를 작성하지 않고 표현식만으로 선언적인 프로그래밍을 할 수 있는 도구이다. 자바에서 람다식을 사용하면 매개변수와 리턴 값의 타입을 생략할 수 있는데, 컴파일러가 문맥을 통해 추론해주기 때문이다.

이때 컴파일러가 타입을 추론하는데 필요한 정보의 대부분을 generic 에서 얻는다. 당연하지만 함수형 인터페이스는 제네릭으로 선언되어 있다.

@FunctionalInterface
public interface Predicate<T> {
  	boolean test(T t);
  	/**
     * default methods...
     */
}

Java 10 이상

var

자바 10부터 타입 추론을 지원하는 var키워드가 추가되었다. 이 키워드는 local variable이면서 선언과 동시에 initializer가 필수적으로 요구된다.

  • 참고 : https://www.baeldung.com/java-10-local-variable-type-inference
    // java 9 이하
    String message = "data";
    // java 10 이상
    var message = "the initializer present on the right-hand side";
    

    We don’t provide the data type of message. Instead, we mark the message as a var, and the compiler infers the type of message from the type of the initializer present on the right-hand side.

    • “컴파일러는 오른쪽에 초기화 값으로 제공되는 것을 통해 타입을 유추한다.”

주의 및 신경써야할 부분

  • 자바 7에서 다이아몬드 연산자라는 방식이 추가되었는데, 자바 10에서 나온 var 와 함께 사용하게 되면 컴파일 에러가 발생한다.
    // 컴파일러가 타입을 유추할 수 있는 정보가 없다.
    var messages = new ArrayList<>();
    
  • 가독성에 있어, 다른 개발자가 읽을때 가독성이 좋을지 고민해야할 것 같다. 다른 사람의 코드를 읽는 경우는 IDE 상에서 코드를 받아 보는 경우도 많겠지만, PR 이 올라와서 github 이나 bitbucket 웹 상으로 보는 경우도 많은 것 같다. 아래 두 경우가 있는데,
    1. 해당 위치만 보고 message 에 어떤 타입의 데이터가 할당될지 알 수 있는 경우
        var message = "문자열 입니다.";
      
    2. 예시에서는 바로 아래 메소드가 있었지만, 다른 클래스 파일에 있는 경우 두 군데 이상의 파일을 조회해야 한다. 그런데 getMessage() 정도는 충분히 코드를 읽는데 방해가 되는 것 같지는 않다. 네이밍을 잘해서 해결할 수 있는 것 같다.
      public void some() {
          var message = getMessage();
    }
        
      public Message getMessage() {
        	// ...
          return new Message("객체입니다.", MessageType.SOME);
      }