从接口vs从父类转换

时间:2016-05-04 19:44:20

标签: java inheritance polymorphism

鉴于课程

public class Dog extends Animal implements Friend{

  ...
}

以下哪项性能更为昂贵?

Dog myDog = (Dog) someAnimal;//where Animal someAnimal

Dog myDog = (Dog) someFriend;//where Friend someFriend

我理解这个问题可能需要一些专业知识来回答,所以谢谢你的帮助。请提供一些有价值的解释。

1 个答案:

答案 0 :(得分:5)

如果你看字节码,它们都不会更贵。我会担心构建和抛出ClassCastExceptions的巨大开销,如果转换失败,则会在任何一种情况下发生 。无论如何,instanceof也不会特别伤害你,如果不能发生演员,你可以减少性能损失。

这里将一个声明为CharSequence(接口)的变量转换为String:

  public static void main(java.lang.String...);
    Code:
       0: ldc           #2                  // String a
       2: astore_1
       3: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
       6: aload_1
       7: checkcast     #4                  // class java/lang/String
      10: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      13: return

将类转换为子类:

  public static void main(java.lang.String...);
    Code:
       0: new           #2                  // class A$B
       3: dup
       4: invokespecial #3                  // Method A$B."<init>":()V
       7: astore_1
       8: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      11: aload_1
      12: checkcast     #2                  // class A$B
      15: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      18: return
}

无论如何,这是instanceof

的影响
  public static void main(java.lang.String...);
    Code:
       0: new           #2                  // class A$B
       3: dup
       4: invokespecial #3                  // Method A$B."<init>":()V
       7: astore_1
       8: aload_1
       9: instanceof    #2                  // class A$B
      12: ifeq          25
      15: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      18: aload_1
      19: checkcast     #2                  // class A$B
      22: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      25: return

正如您所看到的那样,它只是一个额外的字节码操作(通常只会检查对象实例中存在的几个元素)和if语句分支。