public class Test {
public static class Nested<T> {
public T val;
Nested(T val) { this.val = val; }
}
public static void main(String[] args) {
Nested<Integer> a = new Nested<Integer>(5);
Nested<Integer> b = new Nested<Integer>(2);
Integer diff = a.val - b.val;
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码工作正常.但是,如果我向嵌套添加一个方法:
T diff(Nested<T> other) { return this.val - other.val; }
Run Code Online (Sandbox Code Playgroud)
我收到编译错误:
operator - cannot be applied to T,T
Run Code Online (Sandbox Code Playgroud)
这对我来说很有意义.T的类型在运行时被擦除,因此Java不能应用仅为某些类(如Integer)定义的运算符.但为什么a.val - b.val 工作呢?
编辑:
很多好的答案.感谢大家.如果我理解正确的话,它的要点是编译器可以向Integer中添加强制转换,a.val - b.val因为它知道a并b实例化为.但是,由于发生在泛型函数定义的主体内部(其中T仍然可以是任何东西),编译器无法添加使" "工作所必需的强制转换.这导致了一个更有趣的问题,即,如果Java编译器能够内联,那么像diff这样的泛型函数是否可以工作?Nested<Integer>this.val - other.val-
两者之间的区别在于您是在通用方法中还是在其外部.
你得到的绝对正确的方法T是在方法中不知道是Integer,所以运算符减去-不能应用.但是,当你在main(),一般的方法外,编译器知道你实例Nested有Integer,所以它很清楚如何应用操作.尽管泛型的实现已经擦除了生成代码的类型Nested<T>,但编译器并没有考虑a并且b在以下方面Nested<T>:它具有足够的知识来插入适当的强制转换,取消结果,并应用减号-运算符.
您将收到编译时错误,而不是运行时错误.
public static void main(String[] args) {
Nested<Integer> a = new Nested<Integer>(5);
Nested<Integer> b = new Nested<Integer>(2);
Integer diff = a.val - b.val;
}
Run Code Online (Sandbox Code Playgroud)
在这里,编译器知道两者T都是Integer.你刚宣布<Integer>.
T diff(Nested<T> other) { return this.val - other.val; }
Run Code Online (Sandbox Code Playgroud)
在这里,编译器不确定T.它可能是任何东西.而且,只-允许使用数字运算符.
| 归档时间: |
|
| 查看次数: |
316 次 |
| 最近记录: |