Effective Java : 아이템31. 완벽공략 44. 타입추론
- 프로그래밍 언어/JAVA
- 2023. 4. 19.
들어가기 전
- 이 글은 인프런 백기선님의 강의를 복습하며 작성한 글입니다.
이 글의 요약
- 좌측 항에 타입이 명확히 선언되어 있으면, 우측 항에서는 <> 연산자를 이용하면 타입 추론이 가능해진다.
- 메서드의 매개변수가 제네릭일 경우, 메서드 매개변수에 전달되는 인자의 타입에 따라 메서드의 제네릭 타입이 추론 가능해진다.
- 메서드 매개변수에 전달되는 인자의 타입으로 메서드 제네릭 타입이 추론된다면, 반환되는 타입이 어떠한 타입인지 따로 명시할 필요가 없다. BoxExample.<Hello>add() 같은 곳에서 <Hello> 생략 가능하다.
- 메서드 인자로 List<E> 같은 제네릭 타입이 전달되는 경우, 메서드에 구체적인 타입이 선언되어있으면 그 타입으로 타입 추론이 가능해진다.
완벽 공략 44. 타입 추론 (Type Inference)
- 타입추론은 타입을 추론하는 컴파일러의 기능
- 모든 인자의 가장 구체적인 공통 타입 (most specific type)으로 추론한다.
- 제네릭 메서드와 타입 추론
- 메서드 매개변수를 기반으로 타입 매개변수<E>를 추론할 수 있다.
- 제네릭 클래스 생성자를 호출할 때 다이아몬드 연산자 <>를 사용하면 타입을 추론한다.
- 자바 컴파일러는 '타겟 타입'을 기반으로 호출하는 제너릭 메서드의 타입 매개변수를 추론한다
- 자바 8에서 '타겟 타입'이 '메서드의 인자'까지 확장되면서 이전에 비해 타입 추론이 강화되었다.
이 글에서는 자바 컴파일러가 제공하는 타입 추론에 대해서 공부해보고자 한다. 자바에서는 타입 추론을 여러 형태로 추론하기 때문에 편리하게 사용할 수 있다.
타입 추론
타입 추론은 개발자가 어떤 타입을 사용하는지 명시하지 않아도, 자바 컴파일러가 어떤 타입을 쓸지 추론해서 적절한 타입을 넣어주는 것이다.
각종 타입 추론
- 왼쪽에 ArrayList<Box<Integer>가 존재한다. 이 때, 오른쪽은 <> 연산자를 이용해서 생성하면, 컴파일러가 자동으로 타입추론 해준다.
- addBox()는 한정 타입변수 <U>를 사용한다. 이 U는 매개변수로 전달되는 값을 보고 추론한다. 10이 전달되었기 때문에 U는 Integer로 추론된다.
- 매개변수에서 전달된 값으로 충분히 <U>의 타입이 추론되면 리턴 변수의 타입을 의미하는 BoxExample.<Integer>addBox()에서 <Integer>는 생략해도 된다. 이것을 Type Witeness라 하는데, 매개변수를 통해 타입 추론이 완료되었기 때문에 따로 <U>를 정의해 줄 필요가 없다.
- Collections.emptyList()는 List<T>를 반환한다. 이 때 <T>는 좌측 항에 있는 String, Integer 타입을 보고 추론한다.
private static <U> void addBox(U u, List<Box<U>> boxes) {
Box<U> box = new Box<>();
box.set(u);
boxes.add(box);
}
private static void processStringList(List<String> stringList) {
}
public static void main(String[] args) {
// <> 연산자를 이용하면 컴파일러가 타입을 추론해서 생성한다.
ArrayList<Box<Integer>> listOfIntegerBoxes = new ArrayList<>();
// 메서드 매개변수로 충분히 제네릭 타입을 추론할 수 있다. 따라서 반환 타입은 생략해도 된다.
BoxExample.<Integer>addBox(10, listOfIntegerBoxes);
BoxExample.addBox(20, listOfIntegerBoxes);
BoxExample.addBox(30, listOfIntegerBoxes);
BoxExample.outputBoxes(listOfIntegerBoxes);
// Target Type
List<String> stringList = Collections.emptyList(); // 좌측 타입을 보고 추론
List<Integer> integerList = Collections.emptyList(); // 좌측 타입을 보고 추론
BoxExample.processStringList(Collections.emptyList()); // 매개변수가 <String>인 것을 보고 추론
}
메서드의 타입을 보고도 타입 추론 가능
전달되는 메서드의 타입을 보고도 타입 추론이 가능하다.
- Collections.emptyList()는 List<T> 타입을 반환한다. main() 메서드에서는 Collection.emptyList()의 <T>를 추론할 수 없다.
- List<T>는 processStringList() 메서드에 전달된다. 이 때, processStringList의 인자는 List<String>이다. 여기서 <T>는 <String>이 된다.
따라서 Collections.emptyList()의 List<T>는 List<String>으로 추론된다. 이 말은 메서드에 전달되는 매개변수의 타입으로 메서드의 타입을 추론하는 것도 있지만, 메서드의 매개변수 타입 정의가 무엇인지에 따라 외부에서 전달되는 제네릭 인자의 타입도 추론이 가능해진다.
// Collection.java
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
// BoxExample.java
private static void processStringList(List<String> stringList) {
...
}
// BoxExample.java
public static void main(String[] args) {
BoxExample.processStringList(Collections.emptyList()); // 매개변수가 <String>인 것을 보고 추론
}
'프로그래밍 언어 > JAVA' 카테고리의 다른 글
Effective Java : 아이템32. 완벽공략45-46 (1) | 2023.04.20 |
---|---|
Effective Java : 아이템32. 제네릭과 가변인수를 함께 쓸 때는 신중하라 (0) | 2023.04.20 |
Effective Java : 아이템30. 이왕이면 제네릭 메서드로 만들라 (0) | 2023.04.18 |
Effective Java : 아이템29. 완벽공략 43. 한정적 타입 매개변수 (0) | 2023.04.18 |
Effective Java : 아이템29. 이왕이면 제네릭 타입으로 만들라. (0) | 2023.04.18 |