Java 当“Fish f=new BlueFish();”时,内部会发生什么?
假设我们有:Java 当“Fish f=new BlueFish();”时,内部会发生什么?,java,jvm,javac,dynamic-binding,dynamic-dispatch,Java,Jvm,Javac,Dynamic Binding,Dynamic Dispatch,假设我们有: 1 public class DynamicDispatch { 2 public static void main(String[] args) { 3 Fish f = new BlueFish(); 4 f.speak(); 5 } 6 } 7 8 abstract class Fish { 9 abstract String speak(); 10 } 11 12 clas
1 public class DynamicDispatch {
2 public static void main(String[] args) {
3 Fish f = new BlueFish();
4 f.speak();
5 }
6 }
7
8 abstract class Fish {
9 abstract String speak();
10 }
11
12 class BlueFish extends Fish {
13 String speak() {
14 return "I am a blue fish";
15 }
16 }
17
18 class CatFish extends Fish {
19 String speak() {
20 return "I am a cat fish";
21 }
22 }
问题:
从程序集创建了一个BlueFish对象。但是为什么javac没有意识到应该调用BlueFish.speak呢
在运行时,JVM如何处理invokespecial 4,以便调用正确的目标
仅供参考,javap-c输出为:
Compiled from "DynamicDispatch.java"
public class DynamicDispatch extends java.lang.Object{
public DynamicDispatch();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class BlueFish
3: dup
4: invokespecial #3; //Method BlueFish."<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #4; //Method Fish.speak:()Ljava/lang/String;
12: pop
13: return
}
答复:
javac并不试图实现它,因为它很容易造成javac无法很容易发现的情况,甚至根本无法发现。例如,您可以通过用户输入来确定是使用鲶鱼还是蓝鱼
对此,请参见BevynQ的评论。我很惊讶他没有把它作为回答
您可以编译它并查看结果字节码……对象实例有一个在运行时查找的虚拟方法表。该表是在实例化对象时生成的,因此特定于对象的类型。Javac不需要知道对象类型,它只需要从表中选择方法4即可。@BevynQ您能指出一些关于Java虚拟方法表的参考资料吗?谢谢