繁体   English   中英

Java 泛型:多重边界

[英]Java Generics: Multiple Bounds

我有这个代码:

public class Test {

    public static void main(String[] args) {
        Test t = new Test();
        t.callTest();
    }

    public void callTest() {
        GenericTest gt = new GenericTest<Date>(); // this line don't compile
        gt.test(new Date());
    }

    class GenericTest<T extends Date & List> {
        T x;

        public void test(T y) {
            System.out.println(x.toString());
        }
    }
}

我明白为什么new GenericTest<Date>()不能编译,那是因为 Date 没有实现 List 接口,但是如果我实例化GenericTest gt = new GenericTest()没有泛型,整个代码工作,我不明白为什么。 方法 test 期望(T y)其中T extends Date并实现List ,但它适用于gt.test(new Date())

当你像这样实例化时:

GenericTest gt = new GenericTest() 

您使用GenericTest类型的原始版本。 这意味着T类型将被替换为它的第一个绑定(在您的情况下为Date )。 这就是为什么GenericTest#test()的方法契约有一个Date参数,而不是一个List参数。

请注意,除了第一个边界外,每个边界都必须是一个接口。 只有第一个边界可以是一个类。 这样做的原因是不可能有从多个超类继承的类型。

因此,由于只有第一个参数是类,因此您将无法切换类型参数,并且以下类定义将无效:

class GenericTest<T extends List & Date> { }

错误是因为在编译时使用泛型代码进行了更强的类型检查,并且在给定的代码中使用了参数化类型。

正如问题中提到的GenericTest gt = new GenericTest()编译和执行,那只是因为这里调用了 toString() 方法。 如果它是某个 List 接口方法,那么执行时会出现 ClassCastException。 让我们说 size()。

class GenericTest<T extends Date & List> {
        public void test(T y) {
            System.out.println(y.size()); // ClassCastException
        }
}

如果您创建一个没有泛型参数的泛型类实例,编译器会发出警告并且不再控制所创建实例的使用。 至于为什么代码在没有声明泛型类型的情况下工作 - 因为在这种情况下,T 被假定为 Object,任何类型都是好的

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM