Điểm đầu tiên: bạn có thể xóa cảnh báo hoạt động không được chọn bằng cách thay thế đối số Class c
bằng Class<T> c
. Đó có thể là tất cả những gì bạn cần ... trong trường hợp này ... = :-)
Điểm thứ hai: Thông thường mã gọi là SomeContainer.subset() sẽ biết tại loại biên dịch loại U (từ ngữ cảnh logic) . Đây phải là trường hợp của bạn, nếu không bạn sẽ không thể vượt qua Class c
luận trong
Hãy thử:.
class SomeContainer<T> extends ArrayList<T>{
public <U extends T> SomeContainer subset(Class<U> c){
SomeContainer<U> output = new SomeContainer<U>();
// put filtered elements into output
return output;
}
}
Xem những gì tôi đã có?
Giới thiệu tham số loại thứ hai trên cuộc gọi phương thức: U extends T
. Cũng sử dụng điều này trong đối số với Class<U> c
.
Người gọi sẽ gọi tương tự (trong đó X được chọn lớp con của T):
SomeContainer<X> mySubset = mySomeContainer.subset(X.class); // type inference
SomeContainer<X> mySubset = mySomeContainer.<X>subset(X.class); // type arg specified
Nếu bạn cần một cái gì đó nhiều hơn năng động hơn thế này, ký tự đại diện có thể hỗ trợ - cho phép một "gia đình" của parametised loại để được thông qua trong & ra:
public SomeContainer<? extends X> subset(Class<? extends X> c){
This is a "nhựa" giao diện chức năng: bạn có thể trở SomeContainer<T>
hoặc 012.cho bất kỳ X mà là một lớp con của T. Sau đây cũng làm việc:
public SomeContainer<? super Z> subset(Class<? extends X> c){
Tuy nhiên, như một poster đã nói, Generics là một cấu trúc thời gian biên dịch, chúng được thay thế trong quá trình biên dịch với tạo mã không chung chung. Điều này có nghĩa là bạn không thể tự động quyết định loại được sử dụng để khởi tạo một loại chung với một dòng mã.Nhưng bạn có thể gian lận một chút: Nếu bạn có một số lượng giới hạn các lớp con của T, nói X, Y và Z, trong đó Z mở rộng Y, và Y mở rộng Z, thì bạn có thể sử dụng một hacky "if statement" tốt. Hãy thử:
lớp SomeContainer kéo dài ArrayList {
public SomeContainer<? extends X> subset(Class<? extends X> c){
SomeContainer<? extends X> output = null;
// would like to use: "if (c instance of Class<Z>)"
// but instanceof does not allow generic type arguments
if (c.getName().equals(Z.class.getName())) {
SomeContainer<Z> outputZ = new SomeContainer<Z>();
// put filtered elements into outputZ
output = outputZ;
} else if (c.getName().equals(Y.class.getName())) {
SomeContainer<Y> outputY = new SomeContainer<Y>();
// put filtered elements into outputZ
output = outputY;
} else if (c.getName().equals(X.class.getName())) {
SomeContainer<X> outputX = new SomeContainer<X>();
// put filtered elements into outputZ
output = outputX;
}
return output;
}
}
dễ dàng! (hoặc không) = :-)
Cảnh báo là vì bạn đang sử dụng 'Lớp' thay vì' Lớp > '. Và tôi không chắc chắn rằng bạn có thể sử dụng các loại động trong các tham số mẫu. – vainolo
* Vì vậy, nó chỉ chứa các phần tử của một kiểu phụ cụ thể U * Tại sao không khai báo với kiểu phụ cụ thể đó? – m0skit0