2009-09-25 26 views
8

Xin lỗi nếu tiêu đề có vẻ khó hiểu, nhưng một số ví dụ sẽ theo thứ tự.Tại sao không thể loại Chung có chứa loại Chung được gán cho loại Chung loại đã nhập loại ký tự đại diện

Hãy nói rằng tôi có một số lớp Java với một tham số kiểu chung chung:

public class GenericClass<T> { 
} 

tôi có thể tạo một biến gõ để lưu trữ một đối tượng, với tham số chung thiết lập để, nói một String. Java cũng sẽ cho tôi gán biến đó để biến khác nhưng với tham số chung thiết lập để loại wildcard <?>:

GenericClass<String> stringy = ... 
GenericClass<?> generic = stringy; // OK 

Tuy nhiên, khi làm việc với một lớp học với một tham số chung chung, nếu bạn thiết lập các loại tham số mà để được chung chung, bạn có thể không sau đó gán một đối tượng của lớp đó đến một hệt gõ/loại genericized hợp tổ chức đó (nội/lồng) tham số là các loại ký tự đại diện <?>:

GenericClass<GenericClass<String>> stringy = ... 
GenericClass<GenericClass<?>> generic = stringy; // Compile Error 

// And just in case that is confusing, a more 
// realistic example involving Collections: 
List<GenericClass<String>> stringy = ... 
List<GenericClass<?>> generic = stringy; // Compile Error 

các lỗi biên dịch cụ thể là :

Type mismatch: cannot convert from List<GenericClass<String>> to List<GenericClass<?>> 

Trực giác Tôi nghĩ rằng nhiệm vụ được đề cập không phải là vấn đề. Vậy tại sao bài tập này lại là một vấn đề?

+0

Bản sao của http://stackoverflow.com/questions/1341093/nested-generics-with-wildcards – Dirk

Trả lời

8

Vấn đề phải đối mặt của bạn được tính bằng Covariance.

List<GenericClass<String>> stringy = ... 
List<GenericClass<?>> generic = stringy; 
generic.add(new GenericClass<Integer>()); 

Nếu đây không phải là lỗi biên dịch thì dòng cuối cùng của mã sẽ là có thể.

Bạn có thể nhận được xung quanh các lỗi bằng cách làm này:

List<? extends GenericClass<?>> generic = stringy; 

nhưng bạn không thể sử dụng add cũng bởi vì bạn không thực sự biết ? extends GenericClass<?> là gì (Hiệp phương sai một lần nữa). Trong trường hợp này, bạn chỉ có thể liệt kê thông qua Danh sách và mong đợi GenericClass<?>.

4

Về mặt kỹ thuật, đó là vì List<GenericClass<String>> không phải là loại phụ của List<GenericClass<?>>. Để làm cho nó hoạt động, bạn có thể làm một cái gì đó như

List<? extends GenericClass<?>> generic = stringy 

nên hoạt động như mong đợi (mặc dù khá xấu xí ...).

Xem, ví dụ, this SO question để biết thêm chi tiết

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