0

假设我们有:

  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 }

问题

  1. 从程序集中,创建了一个 BlueFish 对象。但是为什么javac没有意识到BlueFish.speak()应该调用呢?

  2. 在运行时,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

}
4

1 回答 1

0

回答:

  1. javac 不会尝试实现它,因为很容易造成 javac 无法轻易发现甚至根本无法发现的情况。例如,您可能会发现是使用CatFish还是BlueFish使用用户输入。

  2. 为此,请参阅 BevynQ 的评论。我很惊讶他没有将其添加为答案。

于 2013-07-16T23:47:49.840 回答