下面这个程序中T 类型不是被擦除了吗?为什么使用get ( ) 方法不需要类型装换? (不适用泛型的简单代码就需要加(String) 来实现类型转换)
擦除知识点在实际编程中体现的多吗?
代码如下:
public class GenericHolder<T> {
private T obj;
public void set(T obj) { this.obj = obj; }
public T get() { return obj; }
public static void main(String[] args) {
GenericHolder<String> holder =
new GenericHolder<String>();
holder.set("Item");
String s = holder.get();
}
}
public class SimpleHolder {
private Object obj;
public void set(Object obj) { this.obj = obj; }
public Object get() { return obj; }
public static void main(String[] args) {
SimpleHolder holder = new SimpleHolder();
holder.set("Item");
String s = (String)holder.get();
}
}
삭제는 런타임 시 일반 클래스 내에서 일반 매개변수에 대한 정보를 얻을 수 없음을 의미합니다. 경계가 지정된 경우 일반 변수의 실제 유형은 경계를 지정하지 않습니다. 즉, obj의 실제 런타임 유형은 Object입니다. get() 메소드를 사용할 때 강제 유형 변환이 필요하지 않은 이유는 제가 올바르게 기억한다면 컴파일러가 변환 코드를 생성하기 때문입니다. , 아마도 처리 후의 상황은 예제 2의 main 메소드의
String s = (String)holder.get()
과 유사할 것입니다. 자세한 내용은 작성자가 javap를 사용하여 디컴파일하여 볼 수 있습니다.두 번째 질문은 소스코드를 읽느냐 안읽느냐와 같다고 생각하는데, 읽지 않으면 프로그래밍에 영향이 없을 것 같습니다. 쓰기 편해요. 아직 학생이고 사실 프로그램은 잘 모르겠네요. 그냥 의견이 좀 그렇네요~
제네릭은 소스 코드에만 반영되며 컴파일 후에는 제공하신 후자의 예와 동일합니다. 따라서 public void test(List list)와 public void test(List list)는 오버로드될 수 없습니다.
Java 파일을 클래스 파일로 컴파일할 때 컴파일 중에 삭제가 수행됩니다. Java의 제네릭은 일종의 설탕 구문으로 간주할 수 있으며, 이를 통해 Java 코드를 작성할 때 더 안전하고 편리해집니다.
Erasure는 실제 작업에서는 사용되지 않습니다. Erasure는 컴파일 타임에 일반적인 구문 설탕의 해석 작업으로 간주될 수 있습니다.
일반 클래스 T new를 사용하는 경우 T는 String으로 지정되며 해당 멤버 변수도 String입니다. 그러나 다른 클래스의 멤버는 Object이고 new
는 그렇지 않습니다. 지정되었으므로 변환이 필요합니다.
Erase는 실제 작업에서는 일반적으로 사용되지 않습니다.
1. 우선 삭제란 일반 태그가 Javac 컴파일러로 전달되어 실행되고 작동한다는 것을 의미합니다. 코드가 컴파일 기간을 지나면 작업 중에 "T"가 무시되고 클래스 파일에서 T를 찾을 수 없습니다. 여기서 유형이 <String>임을 표시하면 컴파일러는 컴파일 중에 GenericHolder에 있는 T를 String 유형으로 변환합니다. 따라서 get을 변환할 필요가 없습니다(컴파일러는 이미 문자열을 인식했습니다).
2. 삭제는 제네릭에서 매우 중요한 개념입니다. 삭제를 이해하지 못하면 제네릭도 이해하지 못한다고 할 수 있습니다. 실제 작업에서 일반적이고 관련된 것은 gson과 같은 프레임워크에서 사용되는 객체의 직렬화 및 역직렬화입니다.
속 으아악GenericHolder<String>
은
과 동일합니다. 으아악실제로는 단지 구문 설탕일 뿐입니다