[아이템 26] 로 타입은 사용하지 말라
Closed this issue · 6 comments
wooody92 commented
[아이템 26] 로 타입은 사용하지 말라
102092 commented
p159 ..런타임에는 제네릭 타입 정보가 지워지므로....
약간 advanced한 질문으로 생각됩니다.
런타임에는 왜 제네릭 정보가 지워지는 걸까요?
한번 알아보면 좋을 것 같습니다
david215 commented
p159 ..런타임에는 제네릭 타입 정보가 지워지므로....
약간 advanced한 질문으로 생각됩니다.
런타임에는 왜 제네릭 정보가 지워지는 걸까요?한번 알아보면 좋을 것 같습니다
- Why?
- 파고 들어가자면 밑도 끝도 없이 어려운 주제...
- Joshua Bloch이 언급한 이유는 Java 5 이전에 존재하던 raw type에 대한 하위 호완성을 유지하기 위함.
- e.g.
List l = new ArrayList();
를 컴파일 에러로 취급하지 않고 경고만 하고 넘어가기.
- e.g.
- What / How?
- Type Erasure?
-
컴파일 전
public class Node<T> { private T data; private Node<T> next; public Node(T data, Node<T> next) { this.data = data; this.next = next; } public T getData() { return data; } // ... }
-
Type erasure 후 (컴파일 중)
public class Node { private Object data; private Node next; public Node(Object data, Node next) { this.data = data; this.next = next; } public Object getData() { return data; } // ... }
-
type paramter
T
가Object
로 바뀌어있는 것을 확인할 수 있다. -
더 자세한 내용은 Erasure of Generic Types
-
- Type Erasure?
david215 commented
Collection<Supertype>
은Collection<Subtype>
의 상위 클래스가 아니다!- 왜?
Collection<Animal>
이Collection<Dog>
의 상위 클래스면Collection<Dog>
에Cat
을 추가할 수 있게 된다...
// Illegal code - because otherwise life would be Bad List<Dog> dogs = new ArrayList<Dog>(); // ArrayList implements List List<Animal> animals = dogs; // Awooga awooga animals.add(new Cat()); Dog dog = dogs.get(0); // This should be safe, right?
- 출처: StackOverflow
- 왜?
- 에러 예시
class A { /* ... */ } class B extends A { /* ... */ } B b = new B(); A a = b; List<B> lb = new ArrayList<>(); List<A> la = lb; // compile-time error
- 그렇기 때문에 와일드카드를 써야한다.
void f(Set<?> s) {} void g(Set<Object> s) {} Set<String> s = new HashSet<>(); f(s); g(s); // compile-time error
- 더 자세한 내용은: Wildcards and Subtyping
kses1010 commented
@102092 아이템 26부터 30번까지 공부해보니 겹치는게 많습니다. 겹치는 부분은 해당 이슈와 링크걸어 이해하기 쉽게 하는것도 나쁘지않을듯 합니다.
kses1010 commented
자바봄의 자바의 제네릭
https://javabom.tistory.com/69?category=835783
Java 컴파일러의 타입 소거
- 제네릭 타입( Example) 에서는 해당하는 타입 파라미터 (T) 나 Object로 변경해준다.
- Object로 변경하는 경우는 unbounded 된 경우를 뜻하며, 이는 <E extends Comparable>와 같이 bound를 해주지 않은 경우를 의미한다.
따라서 이 소거 규칙에 대한 바이트코드는 제네릭을 적용할 수 있는 일반 클래스, 인터페이스, 메서드에만 해당된다. - 타입 안정성 보존을 위해 필요하다면 type casting을 넣어준다.
- 확장된 제네릭 타입에서 다형성을 보존하기 위해 bridege method를 생성한다.