Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.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 当“Fish f=new BlueFish();”时,内部会发生什么?_Java_Jvm_Javac_Dynamic Binding_Dynamic Dispatch - Fatal编程技术网

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虚拟方法表的参考资料吗?谢谢