문서의 선택한 두 판 사이의 차이를 보여줍니다.
| 양쪽 이전 판 이전 판 다음 판 | 이전 판 | ||
|
wiki:java:java-lecture:2week [2021/01/18 08:35] iyyeo [타입 추론, var] |
wiki:java:java-lecture:2week [2023/01/13 18:44] (현재) |
||
|---|---|---|---|
| 줄 288: | 줄 288: | ||
| ==== 타입추론과 Generic Methods ==== | ==== 타입추론과 Generic Methods ==== | ||
| - | 타입추론덕분에 generic 메소드를 사용할 때 보통의 메소드처럼 특정 타입을 명시하지 않은 채로 호출할 수 있다. | + | * 타입추론덕분에 generic 메소드를 사용할 때 보통의 메소드처럼 특정 타입을 명시하지 않은 채로 호출할 수 있다. |
| - | public class BoxDemo { | + | |
| - | public static <U> void addBox(U u, java.util.List< | + | |
| - | Box< | + | |
| - | box.set(u); | + | |
| - | boxes.add(box); | + | |
| - | } | + | |
| - | } | + | |
| - | public static <U> void outputBoxes(java.util.List< | + | } |
| - | int counter = 0; | + | public static <U> void outputBoxes(java.util.List< |
| - | for (Box< | + | int counter = 0; |
| - | U boxContents = box.get(); | + | for (Box< |
| - | System.out.println(" | + | U boxContents = box.get(); |
| - | | + | System.out.println(" |
| - | counter++; | + | |
| + | counter++; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | public static void main(String[] args) { | ||
| + | java.util.ArrayList< | ||
| + | new java.util.ArrayList<> | ||
| + | BoxDemo.< | ||
| + | BoxDemo.addBox(Integer.valueOf(20), | ||
| + | BoxDemo.addBox(Integer.valueOf(30), | ||
| + | BoxDemo.outputBoxes(listOfIntegerBoxes); | ||
| } | } | ||
| } | } | ||
| + | \\ | ||
| + | '' | ||
| + | '' | ||
| + | \\ | ||
| + | ==== 타입추론과 Generic 클래스의 인스턴스 ==== | ||
| + | * Java 컴파일러가 컨텍스트로부터 타입추론이 가능하다면 Generic 클래스의 생성자를 호출하기 위해 필요한 type arguments를 비어있는 type witness(<>, | ||
| + | |||
| + | List< | ||
| + | List< | ||
| + | |||
| + | \\ | ||
| + | ==== 타입추론과 Generic 생성자 ==== | ||
| + | * 클래스가 Generic/ | ||
| + | |||
| + | class MyClass< | ||
| + | <T> MyClass(T t) { | ||
| + | // ... | ||
| + | } | ||
| + | } | ||
| + | | ||
| public static void main(String[] args) { | public static void main(String[] args) { | ||
| - | java.util.ArrayList< | + | MyClass< |
| - | | + | |
| - | BoxDemo.< | + | |
| - | BoxDemo.addBox(Integer.valueOf(20), | + | |
| - | BoxDemo.addBox(Integer.valueOf(30), | + | |
| - | BoxDemo.outputBoxes(listOfIntegerBoxes); | + | |
| } | } | ||
| - | } | + | |
| - | Java | + | * MyClass의 type 매개변수 X에는 Integer가 들어가지만 생성자의 |
| - | (1): addBox라는 generic 메소드를 호출할 때 <Integer> type witness와 함께 type parameter를 명시하여 사용할 | + | \\ |
| - | (2): | + | |
| - | 타입추론과 Generic 클래스의 인스턴스 | + | '' |
| - | Java 컴파일러가 컨텍스트로부터 타입추론이 가능하다면 Generic 클래스의 생성자를 호출하기 위해 | + | '' |
| - | List<String> myList1 = new ArrayList< | + | |
| - | List< | + | MyClass< |
| - | Java | + | |
| - | 타입추론과 Generic 생성자 | + | \\ |
| - | 클래스가 Generic/ | + | ==== Target Types ==== |
| - | class MyClass<X> { | + | * Java 컴파일러는 generic method invocation의 type argument를 추론하기 위해 |
| - | <T> MyClass(T t) { | + | * 표현식의 target |
| - | // ... | + | |
| + | static < | ||
| + | List< | ||
| + | |||
| + | * 위 코드는 Collection API의 emptyList 함수를 이용해 List< | ||
| + | * 이런 데이터 | ||
| + | * 물론, type witness를 사용해 명시적 선언을 해줄 | ||
| + | \\ | ||
| + | List<String> listOne = Collections.< | ||
| + | |||
| + | |||
| + | | ||
| + | \\ | ||
| + | |||
| + | void processStringList(List<String> stringList) { | ||
| + | | ||
| + | } | ||
| + | public static void main(String[] args) { | ||
| + | processStringList(Colections.emptyList()); | ||
| } | } | ||
| - | } | ||
| - | public static void main(String[] args) { | + | * 위 코드에서 메소드 호출은 정상적으로 동작할까? |
| - | MyClass< | + | |
| - | } | + | |
| - | Java | + | |
| - | ⇒ MyClass의 type 매개변수 X에는 Integer가 들어가지만 생성자의 type 매개변수 T에는 String이 들어간다. | + | |
| - | Java SE 7 이전에는 컴파일러에서 실제 type argument를 작성해 타입 추론을 할 수 있었지만, | + | |
| - | MyClass< | + | |
| - | Java | + | |
| - | Target Types | + | |
| - | Java 컴파일러는 generic method invocation의 type argument를 추론하기 위해 target typing의 이점을 이용한다. 표현식의 target type이란 표현식이 나타낸 위치에 의존하여(컨텍스트 의존) Java 컴파일러가 기대하는 데이터 타입이다 | + | |
| - | static <T> List< | + | |
| - | List< | + | |
| - | Java | + | |
| - | 위 코드는 Collection API의 emptyList 함수를 이용해 List< | + | |
| - | 물론, type witness를 사용해 명시적 선언을 해줄 수도 있지만 위 코드에서는 불필요하다. | + | |
| - | List< | + | |
| - | Java | + | |
| - | 하지만, Type Witness가 필요한 경우도 있다. | + | |
| - | void processStringList(List< | + | |
| - | //process stringList | + | |
| - | } | + | |
| - | public static void main(String[] args) { | + | |
| - | processStringList(Colections.emptyList()); | + | |
| - | } | + | |
| - | Java | + | |
| - | ⇒ 위 코드에서 메소드 호출은 정상적으로 동작할까? | + | |
| - | Java SE 7 컴파일러에서는 컴파일 되지 않고 에러가 발생하며 아래와 같은 에러 메세지가 출력된다. | + | |
| - | List< | + | |
| - | 이런 에러가 발생하는 이유는 컴파일러는 type argument T를 위한 value를 필요한데, | + | |
| - | 그렇기에 Java SE 7에서는 type witness를 명시해줘야 한다. | + | |
| - | processStringList(Colections.< | + | |
| - | Java | + | |
| - | 하지만, Java SE 8 부터는 위와 같은 경우에도 type witness를 명시해주지 않아도 Target type을 결정할 때 메소드의 argument도 살피도록 확장되었기 때문에 에러가 발생하지 않는다. | + | |
| - | 그렇기 때문에 Java SE 8이상에서는 위의 type witness가 없는 메소드 호출도 정상적으로 동작할 것이다. | + | |
| - | var | + | |
| - | Java 10부터 추가된 특징중 하나인 Local Variable Type Inference은 로컬 변수 선언을 var를 이용하여 기존의 엄격한 타입 선언방식에서 컴파일러에게 타입추론 책임을 위임할 수 있게 되었다. | + | |
| - | var list = new ArrayList< | + | |
| - | var stream = list.stream();// | + | |
| - | Java | + | |
| - | Local Variable Type Inference 사용 조건 | + | |
| - | • | + | |
| - | 초기화된 로컬 변수 선언시 | + | |
| - | • | + | |
| - | 반복문에서 지역변수 선언 시(enhanced for loop포함) | + | |
| - | var 활용 | + | |
| - | 1. | + | |
| - | 지역변수 선언 | + | |
| - | var numbers = Arrays.asList(1, | + | |
| - | for (var i = 0; i < numbers.size(); | + | List<Object> cannot be converted to List< |
| - | System.out.println(" | + | |
| - | } | + | |
| - | Java | + | |
| - | 2. | + | |
| - | forEach | + | |
| - | var numbers = Arrays.asList(1, | + | |
| - | for (var number : numbers) { | + | * 이런 에러가 발생하는 이유는 컴파일러는 type argument T를 위한 value를 필요한데, |
| - | System.out.println(number); | + | * 그 결과 Collections.emptyList()는 List< |
| - | } | + | * 그렇기에 Java SE 7에서는 type witness를 명시해줘야 한다. |
| - | Java | + | |
| - | ⇒ 기존에는 Object타입으로 받아서 형변환을 하거나 IDE가 아닌 개발자가 직접 타입추론해 명시적 타입선언을 해줬는데 var를 사용하여 훨씬 편하게 타입선언이 가능해진다. | + | processStringList(Colections.< |
| - | 3. | + | |
| - | Lambda (Java 11) | + | * 하지만, Java SE 8 부터는 위와 같은 경우에도 type witness를 명시해주지 않아도 Target type을 결정할 때 메소드의 argument도 살피도록 확장되었기 때문에 에러가 발생하지 않는다. |
| - | IntBinaryOperator plus10 = (@NonNull var one, @NonNull var two) -> one + two + 10; | + | * 그렇기 때문에 Java SE 8이상에서는 위의 type witness가 없는 메소드 호출도 정상적으로 동작할 것이다.\\ |
| - | Java | + | \\ |
| - | ⇒ Java 11부터는 람다 인자에도 var사용이 가능해졌는데, | + | ==== var ==== |
| - | 참고: 비어있는 type witness를 사용하면 Object로 추론한다. | + | * Java 10부터 추가된 특징중 하나인 Local Variable Type Inference은 로컬 변수 선언을 var를 이용하여 기존의 엄격한 타입 선언방식에서 컴파일러에게 타입추론 책임을 위임할 수 있게 되었다. |
| + | |||
| + | var list = new ArrayList< | ||
| + | var stream = list.stream();// | ||
| + | |||
| + | \\ | ||
| + | |||
| + | ==== Local Variable Type Inference 사용 조건 ==== | ||
| + | * 초기화된 로컬 변수 선언시 | ||
| + | * 반복문에서 지역변수 선언 시(enhanced for loop포함) | ||
| + | |||
| + | ==== var 활용 ==== | ||
| + | |||
| + | **1. 지역변수 선언** | ||
| + | |||
| + | var numbers = Arrays.asList(1, | ||
| + | |||
| + | for (var i = 0; i < numbers.size(); | ||
| + | System.out.println(" | ||
| + | } | ||
| + | \\ | ||
| + | |||
| + | **2. forEach** | ||
| + | |||
| + | var numbers = Arrays.asList(1, | ||
| + | |||
| + | | ||
| + | System.out.println(number); | ||
| + | } | ||
| + | |||
| + | |||
| + | * 기존에는 Object타입으로 받아서 형변환을 하거나 IDE가 아닌 개발자가 직접 타입추론해 명시적 타입선언을 해줬는데 var를 사용하여 훨씬 편하게 타입선언이 가능해진다.\\ | ||
| + | \\ | ||
| + | **3. Lambda (Java 11)** | ||
| + | |||
| + | IntBinaryOperator plus10 = (@NonNull var one, @NonNull var two) -> one + two + 10; | ||
| + | |||
| + | | ||
| + | * '' | ||
| ===== Ref ===== | ===== Ref ===== | ||
| - | https:// | + | [[https:// |
| - | https:// | + | |
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | [[https:// | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| {{tag> | {{tag> | ||