Angelica Langer在她关于泛型的常见问题解答中说(见Technicalities.FAQ822):
如果方法具有不同边界的类型参数,则它们不会覆盖,因为这些方法具有不等于覆盖的签名.请记住,类型参数边界是泛型方法签名的一部分.
示例(通用子类型方法重载泛型超类型方法;不推荐):
Run Code Online (Sandbox Code Playgroud)class Super { public <T> void set( T arg) { ... } public <T> T get() { ... } } class Sub extends Super { public <S extends Number > void set( S arg) { ... } // overloads public <S extends Number > S get() { ... } // overloads }
我不明白为什么这个get方法在课堂上重载了Sub.对于我知道它应该是一个编译时错误,因为get在这两个相同的签名Sub和Super(返回类型是不是它的一部分).
什么混淆我更是我使用测试代码的IDE(IntelliJ IDEA的14.0.3)强调get在Sub与下一消息的编译错误:
'Sub'中的'get()'与'Super'中的'get()'冲突; 两种方法都有相同的擦除,但都没有覆盖另一种方法.
但是当我运行程序时,它编译并执行没有问题.我认为IntelliJ在分析代码时存在某种错误,Angelica在她的常见问题解答中说的是正确的.但我无法理解这一点.
我有下一个代码:
ArrayList value = new ArrayList<Integer>(); // 1
value.add("Test"); // 2
Run Code Online (Sandbox Code Playgroud)
我试图理解第2行.虽然我可以看到value.add("Test");编译没有错误,但我看不出它没有抛出运行时异常的原因.如果value引用通用ArrayList对象,为什么Java允许添加一个String?有谁可以向我解释一下?
我在这里描述了我发现的最接近的解释,但我仍然不明白核心原因:
Run Code Online (Sandbox Code Playgroud)Stack s = new Stack<Integer>()这是从参数化类型到原始类型的合法转换.您将能够推动任何类型的价值.但是,任何此类操作都将导致"未经检查的呼叫"警告.