HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🌚
[New] 우기팀
/
득윤
득윤
/
❓
Java Generic
/
6️⃣
타입 이레이저
6️⃣

타입 이레이저

타입 이레이저 Type Erasure

Erasure - 지워 없앰, 말소
 
자바 컴파일러는 타입 이레이져를 아래와 같은 이유로 사용한다.
  • 제네릭 타입(제네릭 클래스, 제네릭 인터페이스)의 모든 타입 파라미터를 Bound Type 혹은 Object 로 변경하여 생성된 바이트 코드에 제네릭 여부를 남기지 않기
 
  • 타입 안정성을 위해 필요하다면 타입 캐스팅을 추가하기
 
  • 제네릭 타입 확장에서 다형성의 안정성을 위해 bridge method 생성하기
 
타입 이레이저는 타입 파라미터를 위해 새로운 클래스를 만드는 것을 막아 제네릭을 런타임 오버헤드 없이 사용할 수 있도록 한다.
 

제네릭 타입 이레이져 Erasure of Generic Type

타입 이레이져 과정에서, 자바 컴파일러는 모든 타입 파라미터를 지우고 bound type 혹은 Object 로 대체합니다.
unbounded T → Object
unbounded T → Object
bounded T → bound type
bounded T → bound type

제네릭 메서드 이레이져 Erasure of Generic Methods

컴파일러는 제네릭 메서드의 타입 파라미터도 bound type 혹은 Object로 바꾼다.
필요없는 타입 파라미터 선언은 제거한다.
 
unbounded T → Object
unbounded T → Object
bounded T → bound type
bounded T → bound type

브릿지 메서드 Bridge Methods

 
public class Node<T> { public T data; public Node(T data) { this.data = data; } public void setData(T data) { System.out.println("Node.setData"); this.data = data; } } public class MyNode extends Node<Integer> { public MyNode(Integer data) { super(data); } public void setData(Integer data) { System.out.println("MyNode.setData"); super.setData(data); } }
MyNode mn = new MyNode(5); Node n = mn; // A raw type - compiler throws an unchecked warning // Note: This statement could instead be the following: // Node n = (Node)mn; // However, the compiler doesn't generate a cast because // it isn't required. n.setData("Hello"); // Causes a ClassCastException to be thrown. Integer x = (Integer)mn.data;
 
타입 이레이져 →
public class Node { public Object data; public Node(Object data) { this.data = data; } public void setData(Object data) { System.out.println("Node.setData"); this.data = data; } } public class MyNode extends Node { public MyNode(Integer data) { super(data); } // Bridge method generated by the compiler // public void setData(Object data) { setData((Integer) data); } public void setData(Integer data) { System.out.println("MyNode.setData"); super.setData(data); } }
Object 타입을 받는 setData 메서드가 컴파일러에 의해 추가 된다.
 

Non-Refiable Types

 
reifiable type : 실행시에도 타입 정보가 남아있는 타입
e.g. int, Integer, List
non-reifiable type: 컴파일시 타입 정보가 손실되는 타입
e.g. List<String> List<Number>
 
JVM은 List<String>과 List<Number>를 구분 할 수 없음
 
See Also) - [Effective Java 3/e] Item 32 제네릭과 가변인수를 함께 쓸 때는 신중하라.