Kyl*_*wey 18 java overloading type-erasure
我有以下代码:
public class Pair< T, U > {
public T first;
public U second;
}
public class Test {
public int method( Pair< Integer, Integer > pair ) {
return 0;
}
public double method( Pair< Double, Double > pair ) {
return 1.0;
}
}
Run Code Online (Sandbox Code Playgroud)
这实际上编译和工作就像人们期望的那样.但是如果返回类型相同,则不会编译,预期的"名称冲突:方法(对)和方法(对)具有相同的擦除"
鉴于返回类型不是方法签名的一部分,这种重载怎么可能?
考虑以下4种方法
Java code bytecode
m1: Byte f(List<Byte> list) f List -> Byte
m2: Long f(List<Byte> list) f List -> Long
m3: Byte f(List<Long> list) f List -> Byte
m4: Long f(List<Long> list) f List -> Long
Run Code Online (Sandbox Code Playgroud)
根据当前的Java语言规范,
m1和m2不能共存,m3和m4也不能共存.因为它们具有相同的参数类型.
m1和m3可以共存,m1和m4也可以共存.因为它们有不同的参数类型.
但是javac 6只允许m1 + m4,而不是m1 + m3.这与方法的字节码表示有关,包括返回类型.因此,m1 + m4可以,但不是m1 + m3.
这是Java和JVM规范看不到的混乱.javac没有"正确"的方式.
虽然很糟糕,但好消息是,重载是一种虚荣,而不是必需品.我们总是可以为这些方法使用不同的,更具描述性和不同的名称.