为什么不能嵌套通配符捕获?

时间:2013-09-20 07:57:52

标签: java generics wildcard

当它“嵌套在另一个通配符中”时,我正在努力捕获通配符。 有可能吗?

代码:

public class ConvolutedGenerics {

    // listClass is a class implementing a List of some Serializable type
    public void doSomethingWithListOfSerializables(
            Class<? extends List<? extends Serializable>> listClass) {

        // Capture '? extends Serializable' as 'T extends Serializable'
        // The line does not compile with javac 7
        captureTheWildcard(listClass); // <------ zonk here
    }

    // listClass is a class implementing a List of some Serializable type
    private <T extends Serializable>
            void captureTheWildcard(
                    Class<? extends List</* ? extends */T>> listClass) {

        // Do something
    }
}
用javac 7编译的

产生:

ConvolutedGenerics.java:18: error: method captureTheWildcard in class ConvolutedGenerics cannot be applied to given types;
                captureTheWildcard(listClass);
                ^
  required: Class<? extends List<T>>
  found: Class<CAP#1>
  reason: no instance(s) of type variable(s) T exist so that argument type Class<CAP#1> conforms to formal parameter type Class<? extends List<T>>
  where T is a type-variable:
    T extends Serializable declared in method <T>captureTheWildcard(Class<? extends List<T>>)
  where CAP#1 is a fresh type-variable:
    CAP#1 extends List<? extends Serializable> from capture of ? extends List<? extends Serializable>
1 error

除了我发现的更简单的案例

但我无法从那些推断出我的问题的答案。

2 个答案:

答案 0 :(得分:2)

你可能已经知道,这是不可能的。

让我用一个反例来说明:

List<Integer> foo = Arrays.asList(1,2,3);
List<String> bar = Arrays.asList("hi","mom");
List<List<? extends Serializable>> baz = Arrays.asList(foo, bar);
doSomethingWithListOfSerializables(baz);

public void doSomethingWithListOfSerializables(
        List<? extends List<? extends Serializable>> listList) {

    captureTheWildcard(listList); 
}

private <T extends Serializable>
        void captureTheWildcard(
                List<? extends List<T>> listList) {

    // Do something
}

T应该是什么?

答案 1 :(得分:0)

您的代码存在的问题是您尝试调用captureTheWildcard传递此处定义的不同类型参数:

private <T extends Serializable> void captureTheWildcard(Class<? extends List<T>> listClass)

您应该在方法定义中明确说明传递的参数实际上是Class<? extends List<? extends Serializable>>的类型,或者像这样修改listClass的类型:

import java.util.List;
import java.io.Serializable;

public class ConvolutedGenerics {

    // listClass is a class implementing a List of some Serializable type                                                                           
    public <T extends Serializable> void doSomethingWithListOfSerializables(
                                                   Class<? extends List<T>> listClass) {

        // Capture '? extends Serializable' as 'T extends Serializable'                                                                             
        // The line does not compile with javac 7                                                                                                   
        captureTheWildcard(listClass); // <------ zonk here                                                                                         
    }

    // listClass is a class implementing a List of some Serializable type                                                                           
    private <T extends Serializable> void captureTheWildcard(Class<? extends List<T>> listClass) {

        // Do something                                                                                                                             
    }
}

与javac 1.7.0_25

编译良好