Java generics

12
Java Generics Jaesup Kwak 2016.11.26

Transcript of Java generics

Page 1: Java generics

Java GenericsJaesup Kwak2016.11.26

Page 2: Java generics

Generic 의 필요성List strList = new ArrayList(); // String 의 리스트를 사용할 의도strList.add(new Integer(0)); // 의도에 맞지 않지만 컴파일러는 모름String str = (String) strList.get(0); // 의도에 맞지만 런타임 예외

(ClassCastException)• 기존 (< Java 1.5) Collection 클래스들 (Wrapper 클래스 ) 의 문제점

• opaque 타입을 활용한 구현이기 때문에• 의도 - 이름 , 주석에 의존• 넣을 때 - 엉뚱한 타입의 객체를 넣게 될 가능성• 꺼낼 때 - 매번 직접 올바른 타입 캐스팅 필요• 매번 조심해야

• 상속을 활용한 매개변수 타입을 갖는 메소드 이용시에도 해당

Page 3: Java generics

해결방안• Collection 이나 Wrapper 클래스의 객체를 생성할 때 컴파일러에게 담을 타입을 한번 알림

• 의도 - 코드에 명확히 나타남• 넣을 때 - 컴파일러가 타입 체크• 꺼낼 때 - 컴파일러가 타입 캐스팅

• 타입을 나타내는 매개변수 (type parameter) 개념의 도입• 메소드에 대해서도 적용 가능한 개념

Page 4: Java generics

사용법 - 정의하기• 제네릭 타입 (generic type)

• class X<T> { T 이용 }• interface X<T> { T 이용 }

• 제네릭 메소드 (generic method)• <T> Result x(T 이용 ) { T 이용 } // Result 에도 T 이용 가능은 함

• 타입 매개변수 (type parameter)• simple: <T>, <U,V>• bounded: <T extends Number>, <T extends

Comparable<T>>

Page 5: Java generics

사용법 - 이용하기• X<String> x = new X<>();• <String>x(…) 혹은 그냥 x(…) // by 타입 추론• 타입 인수 (type argument)

• simple: <String>, <String, Integer>• wildcard:

• unbounded wildcard “?”• upper bounded wildcard “? extends”• lower bounded wildcard “? super”

• 형인자 타입 (parameterized type)• 제네릭 타입의 타입 매개변수에 실제 타입 인수를 지정한 결과 타입• 제네릭 타입의 호출 (invocation of generic type) 이라고도 말함

Page 6: Java generics

generic type 은 불변형 • T2 가 T1 의 하위 타입인 경우 (T2 is-a T1)• 타입 매개변수 T 를 갖는 타입 F 를 F<T> 로 표현할 때

• F<T2> is-a F<T1> 관계이면 F<T> 는 공변형 (covariant)• F<T1> is-a F<T2> 관계이면 F<T> 는 반 ? 변형 (contravariant)• F<T1> 과 F<T2> 에 is-a 관계가 없으면 F<T> 는 불변형 (invariant)

• (Ex)• Integer is-a Number• List<Number> 와 List<Integer> 사이에 is-a 관계가 없다 -> generic type

is invariant• Integer[] is-a Number[] -> array is covariant

Page 7: Java generics

wildcard• ( 문제 ) 제네릭 타입의 불변성은 이를 매개변수로 사용하는 메소드의 재사용성을 크게 제한• ( 해결 ) 메소드 매개변수를 선언할 때 타입 인수로 “ ?” 를 지정하여 임의의 타입 인수를 나타낼 수 있음• ( 결과 ) 임의의 타입 인수를 지정한 해당 제네릭 타입의 객체를 인수로 지정하여 메소드 호출 가능• 타입 인수로 wildcard 지정 가능한 곳

• 멤버 변수 / 지역 변수 / 반환 타입 선언• 타입 인수로 wildcard 지정 불가능한 곳

• 제네릭 메소드 호출 / 제네릭 타입의 객체 생성 / 상위타입 (class X extends Y<?> {})• unbounded wildcard “?”: 임의의 타입 인수와 매칭• upper bounded wildcard “? extends Upper”: Upper 이하의 임의의 타입 인수와 매칭• lower bounded wildcard “? super Lower”: Lower 이상의 임의의 타입 인수와 매칭

Page 8: Java generics

PECS - wildcard 사용 가이드 • Producer Extends Consumer Super• 제네릭 메소드의 인자가 메소드 내에서

• 소스 / 생산자로 사용되는 경우 — > “? extends” 를 사용• 타겟 / 소비자로 사용되는 경우 — > “? super” 를 사용

• 일반적으로 유용하고 견고한 API 를 만드는데 도움• stream 오퍼레이션 , 작업 변수 활용 , Robustness rule 경험칙

• receive, 읽기 : UpperBounded src —> tmp // 관대하게 받아서• send, 쓰기 : tmp —> LowerBounded target // 엄격하게 처리

Page 9: Java generics

타입 소거• 타입 소거 (type erasure) - Java 에서 generic type 을 구현한 방법 / 기법

• 컴파일러는 타입 매개변수와 타입 인수 정보를 활용하여 타입 체크 , 타입 캐스팅 , 브릿지 - 메소드 생성후 generic 관련 타입 정보를 제거하고 컴파일을 수행한다• 생성된 바이트코드에는 타입 매개변수나 타입 인수 정보가 포함되지 않는다

• 브릿지 - 메소드• 제네릭 타입의 하위 클래스에서 타입 매개변수를 사용하는 메소드를 override 한 경우• 상위 클래스에 대한 타입 소거 결과 메소드의 signature 가 변경되어 override 관계가 없어질 수 있다• 이를 해결 하기 위해 컴파일러가 필요에 맞게끔 하위 클래스에 생성하는 메소드• 일반적으로 의식할 필요는 없으나 stack trace 에서 관찰된다 . 놀라지 말라

Page 10: Java generics

실체화 불가 타입 (Non-reifiable)

• 실행시점에 타입에 대한 정보가 완전하지 않음 , 타입 소거의 결과• 실체화 가능 타입

• primitive types• non-generic types• raw types: List• invocations of unbound wildcards: List<?>

• 실체화 불가 타입• <?> 이외의 generic type 호출 : List<String>, List<? extends Number>, List<?

super Integer>• 런타임에 JVM 은 실체화 불가 타입들을 서로 구분할 수 없다• 제네릭의 제약 사항중 많은 부분이 이에 기인함 ( 다음 페이지 )

Page 11: Java generics

제약사항• 기본 타입을 타입 인수로 사용할 수 없다 : <int>• 타입 매개변수로

• 객체 생성할 수 없다 : new T• static 필드를 선언할 수 없다 : static T• 예외를 catch 할 수 없다 : catch (T e) — 반면 , throws 구문에는 사용 가능하다 : void x() throws T

• parameterized type 으로• 타입 테스트할 수 없다 : instanceof List<Integer>• 타입 캐스팅할 수 없다 : (List<Integer>) x• 배열 생성할 수 없다 : new List<Integer>[]

• 타입 소거후 메소드 signature 가 동일하게 되는 오버로딩은 불가능하다• void x(List<String> strList) {}• void x(List<Integer> intList) {}

• 제네릭 예외 클래스를 만들 수 없다 : class MyException<T> extends Exception {}

Page 12: Java generics

참고자료• Oracle, “The Java(TM) Tutorials”,

https://docs.oracle.com/javase/tutorial/java/generics/• Wikipedia, “Covariance and contravariance (computer science)”,

https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)

• 조슈아 블로크 , 이병준 ( 옮김 ), “Effective Java 2/E”