Sự hiểu biết rõ ràng của tôi về Java Generics là cho đến bây giờ, loại Erasure loại bỏ tất cả các loại thông tin như vậy mà không có gì còn lại ở tất cả tại thời gian chạy. Gần đây, tôi tình cờ gặp một đoạn mã mà tôi phải tự hỏi bản thân mình: Cách thức hoạt động của nó? Giản, nó trình bày như sau:Tại sao không phải tất cả thông tin về loại được xóa trong Java khi chạy?
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public abstract class SuperClass<T> {
private final Type type;
protected SuperClass(){
ParameterizedType parameterizedType =
(ParameterizedType) getClass().getGenericSuperclass();
type = parameterizedType.getActualTypeArguments()[0];
}
public void tellMyType(){
System.out.println("Hi, my type parameter is " + type);
}
}
và
public class Example {
public static void main(String[] args) {
SuperClass sc = new SuperClass<Integer>(){};
sc.tellMyType();
}
}
Thi công các kết quả chính Class trong Hi, my type parameter is class java.lang.Integer
.
Những gì chúng ta có thể thấy ở đây là thông tin loại T cũng có sẵn khi chạy, điều này mâu thuẫn với sự hiểu biết ban đầu của tôi.
Vì vậy, câu hỏi của tôi là: Tại sao trình biên dịch giữ điều này? Điều này có bắt buộc đối với một số hành vi JVM nội bộ hoặc có giải thích hợp lý nào về hiệu ứng này không?
Nhận xét ngắn gọn: nếu lớp con của bạn chỉ cần chuyển kiểu generic (như trong 'public class SuperList extends ArrayList '), đầu ra của mã ví dụ (không có bất kỳ lớp ẩn danh nào) sẽ là "Chào, tham số kiểu của tôi là T" –
sfussenegger
Vì vậy, nếu họ đã bỏ qua '{}' trong 'main' (có lẽ sẽ yêu cầu thay đổi constructor thành public), thì thực tế là tham số kiểu là' Integer' sẽ bị mất trong thời gian chạy? – MatrixFrog