T扩展在方法中声明的Object,其中CAP#1是一个新的类型变量

时间:2017-06-15 18:58:56

标签: generics java-8

我正在编译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;
}

1 个答案:

答案 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只是直接退回。