java – Boxing to Object类型以避免编译失败
作者:互联网
参见英文答案 > Why doesn’t autoboxing overrule varargs when using method overloading in Java 7? 3个
请考虑以下代码
public class Foo
{
int value;
public Foo (final String str, Object ... bug)
{
System.out.println ("Should work! 1");
}
public Foo (final String str, final int value, Object ... bug)
{
this.value = value;
System.out.println ("Should work! 2");
}
public static void main (String[]args)
{
Foo f = new Foo ("Foo", 3); //Line 14
System.out.println(f.value);
}
}
当我使用jdk-1.6.x时,我成功地编译了它.
但升级到jdk-1.7后,它给了我错误:
Foo.java:18:错误:对Foo的引用是不明确的,Foo中的构造函数Foo(String,Object …)和Foo中的构造函数Foo(String,int,Object …)匹配
Foo f = new Foo(“Foo”,3); //第14行
所以为了避免这个错误,我改变了第二个Ctor
public Foo (final String str, final Integer value, Object ... bug)
{
this.value = value;
System.out.println ("Should work! 2");
}
这样它就可以自动装箱到Integer并跳过编译错误.
几个问题:
1)这是一个好习惯吗?如果没有那么还有其他方法吗?
2)为什么java开发人员会决定提供错误而不是允许它?
解决方法:
这是设计和Java 6和Java 7之间不兼容的已知区域,因为过载分辨率算法在Java 7中已得到修复.在Java 5和6中,以下代码无法编译:
class Test {
void foo(int... i) {}
void foo(double... d) {}
void test() {
foo(1,2,3);
}
}
编译器会抱怨调用不明确.但这不是真的,因为double比int更通用,因此在这种情况下int是最具体的选项.
但是,此修复导致不兼容(请查看release notes;搜索“varargs”).结果是当你有int和Object时你不能选择最具体的方法,因为它们都不是另一个的子类型.所以这不应该编译.但是,您可以使用Integer,因为Integer是Object的子类型,在这种情况下,它是最具体的选项,因此编译器可以选择它.
发行说明中的相关部分:
While the
javac
compiler accepts more code than it did prior to JDK 7, this fix also results in a slight source incompatibility in the following case:
class Test {
void foo(int... i) {}
void foo(Object... o) {}
void test() {
foo(1,2,3);
}
}
This code compiles in JDK 6 (the most specific method is
foo(int...)
). This code does not compile under JDK 7. As per 07001, it is not possible to choose betweenfoo(int...)
andfoo(Object...)
as neitherint
is a subtype ofObject
, norObject
is a subtype ofint
. This program should be disallowed (in fact, it should never have been allowed in the first place).Nature of Incompatibility: behavioral and source
RFE: 07002
标签:java,java-7,autoboxing 来源: https://codeday.me/bug/20190901/1780418.html