具有较低有界类型的Java类型推断

shm*_*sel 6 java generics type-inference bounded-wildcard

为什么Java可以推断多个上限类型的共同祖先,而不是下限类型的共同祖先?

更具体地说,请考虑以下示例:

static class Test {

    static <T> T pick(T one, T two) {
        return two;
    }

    static void testUpperBound() {
        List<? extends Integer> extendsInteger = new ArrayList<>();

        // List<? extends Integer> is treated as a subclass of List<? extends Number>
        List<? extends Number> extendsNumber = extendsInteger;

        // List<? extends Number> is inferred as the common superclass
        extendsNumber = pick(extendsInteger, extendsNumber);
    }

    static void testLowerBound() {
        List<? super Number> superNumber = new ArrayList<>();

        // List<? super Number> is treated as a subclass of List<? super Integer>
        List<? super Integer> superInteger = superNumber;

        // The inferred common type should be List<? super Integer>,
        // but instead we get a compile error:
        superInteger = pick(superNumber, superInteger);

        // It only compiles with an explicit type argument:
        superInteger = Test.<List<? super Integer>>pick(superNumber, superInteger);
    }
}
Run Code Online (Sandbox Code Playgroud)

shm*_*sel 2

我想我可以解释为什么 Java 区分下限类型和上限类型。

Integer当使用不兼容的边界(例如和 )时,尝试推断公共下限可能会失败Long。当我们使用上限时,总是可以找到一些共同的上限,在本例中是List<? extends Number>List<? super Integer>但和没有共同的下界List<? super Long>。发生此类冲突时唯一安全的选择是 return List<? extends Object>,与 同义List<?>,意思是“List未知类型”。

现在,可以说,只有当实际上存在冲突的界限时,我们才可以诉诸于此,而不是我的问题中的情况。但也许决定采取简单的方法,除非明确指定,否则不假设存在共同的下限。