728x90
Generic Type Erasure
- Java에서는 제네릭 클래스를 인스턴스화 할 때 해당 타입을 지운다. 그 타읍은 컴파일시에만 존재하고 컴파일된 코드에서는 어떠한 타입 파라미터의 정보를 찾아볼 수 없다.
제네릭의 컴파일의 과정
//자바코드
public void test(){
List<String> strings = new ArrayList<>();
}
//바이트 코드
public test()V
L0
LINENUMBER 8 L0
NEW java/util/ArrayList
DUP
INVOKESPECIAL java/util/ArrayList.<init> ()V
ASTORE 1
L1
LINENUMBER 9 L1
RETURN
L2
LOCALVARIABLE this Lexample/lezhin/timeline/controller/TestController; L0 L2 0
LOCALVARIABLE strings Ljava/util/List; L1 L2 1
// signature Ljava/util/List<Ljava/lang/String;>;
// declaration: strings extends java.util.List<java.lang.String>
MAXSTACK = 2
MAXLOCALS = 2
}
//그래서 자바코드의 변경
public void test(){
List strings = new ArrayList<>();
}
- 제레닉 타입에서는 해당하는 타입 파라미터나 Object로 변경한다.
- Object로 변경하는 경우는 unbounded 된 경우를 뜻하며, 이는 <E extends Comparable>롸 같이 bound를 해주지 않은 경우를 의미한다.
- 따라서 이 소거 규칙에 대한 바이트코드는 제네릭을 적용할 수 있는 일반 클래스, 인터페이스, 메서드에만 해당한다.
- 타입 안정성 보존을 위해 필요하다면 type casting을 넣어준다.
- 확장된 제네릭 타입에서 다형성을 보존하기 위해 bridge method를 생성한다.
// unbound type 예시
//소거 전
public class Test<T>
public void test(T test){
System.out.println(test.toString());
}
}
//소거 후
public class Test {
public void test(Object test) {
System.out.println(test.toString());
}
}
// bound type 예시
public class Test<T extends Comparable<T>> {
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
------------------------
public class Test {
private Comparable data;
public Comparable getData() {
return data;
}
public void setData(Comparable data) {
this.data = data;
}
}
// Object가 아닌 Comparable 으로 변경한다.
// bridge method 예시
// 소거 전
public class MyComparator implements Comparator<Integer> {
public int compare(Integer a, Integer b) {
//
}
}
// 소거 후
public class MyComparator implements Comparator {
public int compare(Integer a, Integer b) {
//
}
}
// bridge method 적용시
public class MyComparator implements Comparator<Integer> {
public int compare(Integer a, Integer b) {
//
}
//THIS is a "bridge method"
public int compare(Object a, Object b) {
return compare((Integer)a, (Integer)b);
}
}
-Reference
'Java' 카테고리의 다른 글
Static (정적) (0) | 2022.04.02 |
---|---|
대용량 요청 시 API limit (0) | 2022.03.15 |
자바의 컴파일 과정 (0) | 2021.10.31 |
[JAVA] Wrapper Class와 일급 컬렉션 (0) | 2021.10.17 |
[JAVA] Lambda와 Stream (0) | 2021.10.09 |