我正在编译java 8中的现有代码,我看到了这个警告:
where T is a type-variable:
T extends Object declared in method <T>mtd1(...)
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
以下是显示此警告的电话:
IExample<T> model = (IExample<T>) Utils.getModel(x.getModel());
这里是getModel方法:
public static IExample<?> getModel(Class1 model) {
if (model instanceof IExample<?>) {
return (IExample<?>)model;
} else if (model instanceof Class2){
return getModel(((Class3)model).getActualModel());
} else {
return null;
}
}
我经历了这个article并实现了一个如下的帮助方法:
private static <T> IExample<T> mtd1Helper (IExample<T> model) {
return (IExample<T>) model;
}
并将调用更改为以下内容,但即使在此之后,它也要我明确地执行转换为(IExample),然后我仍然会看到警告。
IExample<T> model = mtd1Helper(Utils.getModel(x.getModel()));
我缺少什么?
以下是代码的相关部分:
private static <T> void mtd1(final JTable table) {
...
IExample<T> model = (IExample<T>) Utils.getModel(table.getModel());
...
}
public static IExample<?> getModel(Class1 model) {
if (model instanceof IExample<?>) {
return (IExample<?>)model;
} else if (model instanceof Class2){
return getModel(((Class3)model).getActualModel());
} else {
return null;
}
}
而且,这是我修改它的方式:
private static <T> void mtd1(final JTable table) {
...
IExample<T> model = mtd1Helper(Utils.getModel(x.getModel()));
...
}
private static <T> IExample<T> mtd1Helper (IExample<T> model) {
return (IExample<T>) model;
}
答案 0 :(得分:1)
我不确定你错了,因为你没有把整个代码放在上面,但我可以给你一些建议。我希望它可以帮助你。
List<?>
相当于List<? extends Object>
。这意味着您无法添加除null
之外的任何内容,它通常用于读取模式。例如:
List<?> list = new ArrayList<>();
list.add(null);//ok
list.add(new Object()); //error
对于写入模式,您可以使用List<? super Object>
,例如:
List<? super Object> list = new ArrayList<>();
list.add(new Object());//ok
但可以将List<*>
分配给List<?>
,例如:
List<? super Object> list = new ArrayList<>();
List<? extends Object> list2 = list; // ok
这就是为什么通配符捕获需要帮助方法,因为List<T>
可以读取 T
和写 a {{1}的值价值。
T
但是当您通过void foo(List<?> i) {
fooHelper(i);
}
private <T> void fooHelper(List<T> l) {
l.set(0, l.get(0));
}
两次时,会再次出现错误,例如:
i
注意:这意味着您必须在void foo(List<?> i) {
fooHelper(i,i);
// ^--- wildcard capture error
}
private <T> void fooHelper(List<T> l,List<T> r) {
l.set(0, r.get(0));
}
内操作(阅读&amp; 编写)List<T>
方法,但您的fooHelper
只是直接退回。