Java方法调度如何与泛型和抽象类一起使用?

rcr*_*ick 7 java generics overloading

我遇到了今天Java没有调用我预期的方法的情况 - 这是最小的测试用例:(对不起,这似乎是人为的 - '真实世界'场景要复杂得多,而且更有意义从"究竟为什么会怎么做?"的立场.)

我特别感兴趣的是为什么会这样,我不关心重新设计的建议.我有一种感觉,这是在Java Puzzlers,但我没有我的副本方便.

请参阅以下Test <T> .getValue()中的具体问题:

public class Ol2 {  

    public static void main(String[] args) {  
        Test<Integer> t = new Test<Integer>() {  
            protected Integer value() { return 5; }  
        };  

        System.out.println(t.getValue());  
    }  
}  


abstract class Test<T> {  
    protected abstract T value();  

    public String getValue() {  
        // Why does this always invoke makeString(Object)?  
        // The type of value() is available at compile-time.
        return Util.makeString(value());  
    }  
}  

class Util {  
    public static String makeString(Integer i){  
        return "int: "+i;  
    }  
    public static String makeString(Object o){  
        return "obj: "+o;  
    }  
} 
Run Code Online (Sandbox Code Playgroud)

此代码的输出是:

obj: 5
Run Code Online (Sandbox Code Playgroud)

Dar*_*ron 6

不,编译时无法使用值类型.请记住,javac只会编译一个代码副本,用于所有可能的T代码.鉴于此,编译器在getValue()方法中使用的唯一可能类型是Object.

C++是不同的,因为它最终将根据需要创建代码的多个编译版本.