第一点:您可以删除未检查的操作警告,将Class c
参数替换为Class<T> c
。这可能是你所需要的......在这种情况下... = :-)
观点二: 通常调用SomeContainer.subset()的代码就知道在编译输入型U(从逻辑上下文) 。这必须是你的情况下,否则你将无法通过在Class c
参数
尝试:
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;
}
}
见我做什么呢?
在方法调用中引入第二个类型参数:。 也在Class<U> c
的论点中使用了这个。
调用者将调用像(其中X是选择的T子类):
SomeContainer<X> mySubset = mySomeContainer.subset(X.class); // type inference
SomeContainer<X> mySubset = mySomeContainer.<X>subset(X.class); // type arg specified
如果你需要的东西比这更动态,通配符可以帮助 - 允许的parametised“家庭”
public SomeContainer<? extends X> subset(Class<? extends X> c){
这是一个“塑料”功能界面:类型在&出传递你可以返回SomeContainer<T>
或SomeContainer<X>
对于任何X是T的子类下面也适用:
public SomeContainer<? super Z> subset(Class<? extends X> c){
然而,作为另一的海报所说,泛型是编译时构建体,它们在替换产生的非通用代码编译。这意味着你不能动态地决定用一行代码实例化泛型的类型。但是你可以作一些小小的尝试:如果你的T的子类数量有限,比如说X,Y和Z,其中Z扩展Y,Y扩展Z,那么你可以使用一个很老的哈希“if语句”。尝试:
类SomeContainer扩展的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;
}
}
轻松! (或不)= :-)
警告是因为您正在使用'Class'而不是'Class >'。我不确定你可以在模板参数中使用动态类型。 – vainolo
*因此它只包含特定子类型U的元素*为什么不用该特定子类型U声明? – m0skit0