Java方法派生如何与泛型和抽象类一起工作? [英] How does Java method dispatch work with Generics and abstract classes?

查看:180
本文介绍了Java方法派生如何与泛型和抽象类一起工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天我遇到了一种情况,那就是Java没有调用我期望的方法 - 这是最简单的测试用例:(我很抱歉,这看起来很有意思 - 真实世界的场景要复杂得多,从为什么你会这么做这个观点来看更有意义)。



我特别感兴趣的是为什么会发生这种情况,我不在乎重新设计的建议。



请参阅Test< T> .getValue()中的具体问题以表明您对此感兴趣。如下:

  public class Ol2 {

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

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


抽象类Test< T> {
保护抽象T值();

public String getValue(){
//为什么总是调用makeString(Object)?
//值的类型()在编译时可用。
返回Util.makeString(value());


$ b $ class Util {
public static String makeString(Integer i){
returnint:+ i;
}
public static String makeString(Object o){
returnobj:+ o;


这段代码的输出是:

  obj:5 


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



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


I ran into a situation today where Java was not invoking the method I expected -- Here is the minimal test case: (I'm sorry this seems contrived -- the 'real world' scenario is substantially more complex, and makes much more sense from a "why the hell would you do that?" standpoint.)

I'm specifically interested in why this happens, I don't care about redesign suggestions. I have a feeling this is in Java Puzzlers, but I don't have my copy handy.

See the specific question in commends within Test<T>.getValue() below:

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;  
    }  
} 

The output from this code is:

obj: 5

解决方案

No, the type of value is not available at compile time. Keep in mind that javac will only compile one copy of the code to be used for all possible T's. Given that, the only possible type for the compiler to use in your getValue() method is Object.

C++ is different, because it will eventually create multiple compiled versions of the code as needed.

这篇关于Java方法派生如何与泛型和抽象类一起工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆