개념정리

타입추론

춘핑이 2023. 3. 15. 16:48

1. 타입추론 이란?

타입추론은 말그대로 개발자가 변수의 타입을 명시적으로 적어주지 않고도
컴파일러가 알아서 이 변수의 타입을 대입된 리터럴로 추론하는 것이다.
대표적인 타입추론 언어는 자바스크립트, 코틀린, 스위프트 등이 있다.

자바는 참조변수 타입으로 인스턴스의 타입을 추론할 수 있다.
또한 람다식에서는 파라미터의 타입으로 인해서 타입을 추론할 수 있다.

제네릭에서의 타입추론

Box<String> box1 = new Box<String>();
Box<String> box2 = new Box<>();

List<List<Integer>> list1 = new ArrayList<List<Integer>>();
List<List<Integer>> list2 = new ArrayList<>();

람다식 타입추론

MyInterface01 o1 = (int a, String b) -> b;
MyInterface01 o2 = (a, b) -> b;

2. 지역변수 var

var은 Java10에서 도입되었다.
변수를 선언할 때 타입을 생략할 수 있고 컴파일러가 타입을 추론한다.
(Local-Variable Type Inference)

컴파일 타임에 추론하는 것이기 때문에,
Runtime에 추가 연산을 하지 않아 성능에 영향을 주지는 않는다고 한다.
그리고 var는 지역 변수에서만 사용할 수 있다.
컴파일러가 타입을 추론할 수 없는 애매한 상황일 때 컴파일 에러가 발생한다.

1. var으로 변수 선언

Java 9 이하에서는 변수를 선언할 때 타입을 명시적으로 선언해야했다.
Java 10부터는 var로 타입 선언 없이 값을 선언할 수 있다.
자바컴파일러가 자체적으로 들어오는 값을 보고 타입을 추론하는 것이다.

다른 클래스들도 var로 변수를 선언할 수 있다.
ArrayList와 같은 객체도 선언할 수 있다.

var list = new ArrayList<String>();

1.1 반복문

var은 반복문에서 사용할 수도 있다.

for (var n : arr) {
    System.out.println("n : " + n);
}

2. 제약 사항

다음과 같은 경우에 타입 추론을 할 수 없어 컴파일 에러가 발생한다.
이런 경우 명시적으로 타입을 지정해줘야 한다.

2.1 지역 변수에서만 사용

클래스의 멤버변수(전역변수)를 선언할때는 사용할 수 없다.

2.2 초기화 필요

초기화를 하지 않으면 어떤 타입인지 추론할 수 없기 때문에 컴파일 에러가 발생한다.

2.3 null로 초기화할 수 없음

어떤 객체든 null이 할당될 수 있기 때문에
타입 추론을 할 수 없으며 컴파일 에러가 발생한다.

2.4 배열에 사용할 수 없음

배열을 사용할 때도 타입 추론을 못하기 때문에
명시적으로 타입을 정해줘야 한다.

2.5 Lambda에 사용할 수 없음

Lambda에도 사용할 수 없다.

2.6 값의 타입 변경이 불가하다.

컴파일단계에서 들어오는 값에 따라 타입을 이미 정해두는 것이다.
그래서 중간에 값의 타입이 바뀔 수 없다.

생각보다 제약이 너무많은데 왜 사용하나?
Java 11에서는 람다 표현식에 var를 사용할 수 있고
var 타입을 지정함으로 인해 어노테이션을 추가할 수 있다고한다.