Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java方法分派如何处理泛型和抽象类?_Java_Generics_Overloading - Fatal编程技术网

Java方法分派如何处理泛型和抽象类?

Java方法分派如何处理泛型和抽象类?,java,generics,overloading,Java,Generics,Overloading,今天我遇到了一种情况,Java没有调用我所期望的方法——这是一个最小的测试用例:(很抱歉,这似乎是人为的——‘真实世界’的场景要复杂得多,从“你到底为什么要这么做?”的角度来看,这更有意义。) 我特别感兴趣的是为什么会发生这种情况,我不关心重新设计的建议。我有一种感觉,这是在Java拼图,但我没有我的副本手边 请参阅下面Test.getValue()中的具体问题: 否,值的类型在编译时不可用。请记住,javac只编译一个代码副本,用于所有可能的T。鉴于此,编译器在getValue()方法中唯一可

今天我遇到了一种情况,Java没有调用我所期望的方法——这是一个最小的测试用例:(很抱歉,这似乎是人为的——‘真实世界’的场景要复杂得多,从“你到底为什么要这么做?”的角度来看,这更有意义。)

我特别感兴趣的是为什么会发生这种情况,我不关心重新设计的建议。我有一种感觉,这是在Java拼图,但我没有我的副本手边

请参阅下面Test.getValue()中的具体问题:


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


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

因为关于使用什么
makeString()
的决定是在编译时做出的,并且基于T可以是任何东西的事实,必须是
对象
版本。想想看。如果执行了
Test
,则必须调用
对象
版本。因此,
Test
的所有实例都将使用
makeString(Object)

现在,如果您做了如下操作:

public abstract class Test<T extends Integer> {
  ...
}
公共抽象类测试{
...
}
事情可能会有所不同。

Josh Bloch的高效Java进行了精彩的讨论,澄清了出现的困惑,因为对于重载和重写(在子类中)方法,分派的工作方式不同。重载方法中的选择——这个问题的主题——是在编译时确定的;在重写的方法中进行选择是在运行时完成的(因此可以获得对象特定类型的知识)

这本书比我的评论要清楚得多:见
“第41项:明智地使用重载”

Ah。。。我曾认为java泛型被编译得更像C++模板。谢谢
obj: 5
public abstract class Test<T extends Integer> {
  ...
}