2013-09-27 50 views
5

Tại sao điều này xảy ra. Nếu tôi vượt qua lớp chung ẩn danh để gõ phương pháp xác định - tất cả đều tốt. Nhưng nếu tôi vượt qua đối tượng trong phương pháp này - giao diện điều khiển đầu ra là E.Xác định loại chung loại thời gian chạy

public static void main(String[] args) { 

    printType(new ArrayList<Integer>() {}); 
    printType(new ArrayList<Integer>()); 

} 

public static void printType(final List<?> list) { 
    System.out.println(((ParameterizedType) list.getClass().getGenericSuperclass()).getActualTypeArguments()[0]); 
} 

Console:

class java.lang.Integer 

E 

hãy giải thích cho tôi.

+0

bạn đang cố gắng làm gì? –

+0

bạn đang in typeparameter của danh sách –

+0

Tôi đang cố gắng lấy tham số kiểu trong thời gian chạy –

Trả lời

7

Lệnh gọi đầu tiên là chuyển một phiên bản của một phân lớp ẩn danh là ArrayList<Integer>. Vì vậy, nó tương tự như:

class YourClass extends ArrayList<Integer> 

và bạn gọi phương pháp này là:

printType(new YourClass()); 

Các lớp cha chung của YourClass hoặc lớp vô danh trong trường hợp của bạn là chỉ ArrayList<Integer>. Vì vậy, đầu ra đó là rõ ràng.


Đối với trường hợp thứ 2 của bạn, bạn đang chuyển trường hợp ArrayList<Integer>. Và định nghĩa của lớp này trông giống như:

public class ArrayList<E> extends AbstractList<E> 
     implements List<E>, RandomAccess, Cloneable, java.io.Serializable 

Vì vậy, lớp học chung ở đây là AbstractList<E>.

õ của generic loại cổ phiếu cùng Class dụ:

Lưu ý rằng tất cả các instantiation của ArrayList chia sẻ cùng lớp trong thời gian chạy:

new ArrayList<Integer>().getClass() == new ArrayList<String>().getClass(); 

Việc so sánh trên sẽ cung cấp cho bạn true. Bởi vì cả hai getClass() gọi cho hệ lại với bạn:

class java.util.ArrayList 

Xem JLS 8.1.2: Generic Classes and Type Parameters:

Một tuyên bố chung lớp định nghĩa một tập các kiểu tham số (§4.5), một cho mỗi invocation thể loại tham số phần theo đối số loại. Tất cả các loại tham số này chia sẻ cùng một lớp vào thời gian chạy.

Ví dụ, thực hiện mã:

Vector<String> x = new Vector<String>(); 
    Vector<Integer> y = new Vector<Integer>(); 
    boolean b = x.getClass() == y.getClass(); 

sẽ dẫn đến việc biến b giữ giá trị true.

Nói cách khác, getGenericSuperClass() phương pháp sẽ không cung cấp cho bạn những đối số kiểu thực tế mà bạn sử dụng trong khi instantiating lớp học của bạn, nhưng tham số kiểu sử dụng trong lớp nó được mở rộng. Bây giờ, vì siêu lớp chung của java.util.ArrayListAbstractList<E>. Và do đó thông số loại bạn nhận được sẽ chỉ là E.

Các vấn đề liên quan