본문 바로가기
Language/Java

[Java] 제네릭은 처음부터 있었던 문법이 아니다(feat. raw type, type eraser)

by 클레어몬트 2024. 9. 16.

ㅇraw type: 다이아몬드(<>)를 사용하는 일반적인 제네릭 방식과는 다르게, 다이아몬드를 사용하지 않는 방식

내부의 타입 매개변수가 Object로 사용된다고 이해하면 된다

GenericBox integerBox = new GenericBox();

자바의 제네릭은 자바가 처음 등장할 때부터 있었던 것이 아니라, Java 5 이후에 등장했기 때문에 제네릭이 없던 시절의 과거 코드와 호환이 필요했다. 그래서 어쩔 수 없이 이런 raw type을 지원하는 것이다따라서 우리가 코드를 작성할 때는 raw type을 사용할 이유가 없다.

※ raw type은 Java에만 있는 독특한 개념이다

 

 

 

type eraser도 마찬가지로 이해하면 된다

ㅇtype eraser: 컴파일 시점에 제네릭 타입 정보를 제거하고 raw type으로 변환하는 과정

제네릭은 자바 컴파일 단계에서만 사용되고, 컴파일 이후에는 제네릭 정보가 삭제된다. 컴파일 전인 .java에는 타입 매개변수가 존재하지만, 컴파일 이후인 바이트코드 .class에는 타입 매개변수가 존재하지 않는다. 

 

[소스코드]

package generic.ex5;

public class EraserBox<T> {
    public boolean instanceCheck(Object param) {
        return param instanceof T; // 컴파일 오류
    }

    public void create() {
        return new T(); // 컴파일 오류
    }
}

 

[런타임]

package generic.ex5;

public class EraserBox<T> {
    public boolean instanceCheck(Object param) {
        return param instanceof Object; // T가 Object로 되기 때문에 컴파일 오류
    }

    public void create() {
        return new Object(); // T()가 Object()로 되기 때문에 컴파일 오류
    }
}

 

T는 런타임에 모두 Object가 되어버린다. 만약 T의 상한이 Animal(T extends Animal) 이라면 런타임에 T는 모두 Animal이 되어버린다. 따라서 자바는 타입 매개변수에 new를 허용하지 않는다.(타입 이레이저 방식의 한계)