当涉及泛型时,Java8选择了与Java7不同的重载方法

当涉及泛型时,Java8选择了与Java7不同的重载方法,java,type-inference,overloading,Java,Type Inference,Overloading,我有以下测试课程: import java.io.Serializable; public class Java8Problem { public void test(String stringArg) { System.out.println("string-Method taken: " + stringArg); } public void test(Object objectArg) { System.out.println("

我有以下测试课程:

import java.io.Serializable;
public class Java8Problem {

    public void test(String stringArg) {
        System.out.println("string-Method taken: " + stringArg);
    }

    public void test(Object objectArg) {
        System.out.println("object-Method taken: " + objectArg.toString());
    }

    public <T extends Serializable> T getTestData() {
        return (T) new Integer(10);
    }

    public static void main(String[] arguments) {
        Java8Problem instance = new Java8Problem();
        instance.test(instance.getTestData());
    }

}
import java.io.Serializable;
公共类Java8Problem{
公共无效测试(字符串stringArg){
System.out.println(“采用的字符串方法:“+stringArg”);
}
公共无效测试(对象objectArg){
System.out.println(“采用的对象方法:+objectArg.toString());
}
公共T getTestData(){
返回(T)新整数(10);
}
公共静态void main(字符串[]参数){
Java8Problem实例=新的Java8Problem();
test(instance.getTestData());
}
}
当我在Java 7中编译并运行该类时,输出将是:

目标方法:10

但是当我在Java 8中编译并运行这个类时,我得到了一个运行时异常:

线程“main”java.lang.ClassCastException中的异常: 无法将java.lang.Integer转换为java.lang.String 位于Java8Problem.main(Java8Problem.java:21)

因此,Java8似乎采用了最具体的方法,而Java7采用了最常见的方法

是否有人知道这是Java8中的一个bug,或者它是否改变了/期望的行为?如果是后者,是否有可能将Java8配置为使用旧的行为?或者有没有其他办法解决这个问题


顺便说一句:我知道这里的问题是由方法getTestData的返回类型引起的,但这只是我现实世界问题的一个简化示例,我无法轻松更改该方法的签名。

这里有一个解决方法,让编译器在Java 8中选择
公共无效测试(objectobjectarg)
,从而避免了
ClassCastException

Java8Problem instance = new Java8Problem ();
instance.test(instance.<Integer>getTestData());
Java8Problem实例=新的Java8Problem();
test(instance.getTestData());

最好指定您确切使用的java版本。例如,在1.8.0_05中有许多与泛型和lambdas相关的bug。我认为这已经得到了详细的解释,使用的java版本是1.8.0_151,特定的java版本几乎不相关;这将发生在所有JDK版本8+AFAIK上,这是预期的行为(请参阅标记的副本)。