【问题标题】:Java beginner: does casting result in lower performance by any mean?Java初学者:强制转换是否会导致性能下降?
【发布时间】:2010-12-28 12:01:22
【问题描述】:

当我创建 Animal x=new Dog(); 并且我想使用 Dog 函数时,我必须强制转换吗? ((Dog)x).bark(); 所以假设我会在 for 循环中多次使用它会导致性能降低吗?除了每次都投射还有其他方法吗?

【问题讨论】:

  • 您可能问错了问题。 “将 Animal 创建为 new Dog() 然后使用 Dog 函数”暗示了一个有问题的设计。
  • @大卫,伙计!你的评论让我改变了整个程序,是的,你是对的,非常感谢!

标签: java inheritance casting


【解决方案1】:

演员表

Dog dog = (Dog) animal;

是所谓的“检查”演员表。所以在运行时它是一个简单的 if 语句(是实现 Dog 的动物实例),它会抛出一个ClassCastException。因此,如果强制转换正常,至少它不会提供任何合理的性能开销,但如果它失败,则会抛出异常,并且异常处理是一项消耗性能的“操作”。

因此,如果您施放某些东西,并且施放不会失败,我相信没有性能问题。但是如果你有一个经常失败的演员表,那么你应该稍微改变你的算法。

【讨论】:

【解决方案2】:

强制转换总是会增加开销,但很难说它是否会成为应用程序的瓶颈。这将取决于您的情况。您可以通过在循环之外执行它来避免多次转换:

Animal x = new Dog();
Dog dog = (Dog)x;
Now loop and call dog.bark() as many times as you like

【讨论】:

    【解决方案3】:

    我倾向于在返回 Base 类型时在本地使用实现类型。像这样的:

    public Animal createAnimal(){
        Dog dog = new Dog();
        dog.bark();
        dog.bite();
        dog.houl();
        return dog;
    }
    

    【讨论】:

      【解决方案4】:

      假设 Dog 类是这样的:

      package test;
      public class Dog extends Animal {
          public void bark(){
              System.out.println("Woof woof");
          }
      }
      

      Animal 类是这样的:

      package test;
      public class Animal {
          public void sayHello(){
              System.out.println("Hello !!");
          }
      
          public static void main(String[] args) {
              Animal a = new Dog();
              a.sayHello();
              ((Dog)a).bark();
          }
      }
      

      如果您看到生成的字节码,它将如下所示:

      Compiled from "Animal.java"
      public class test.Animal extends java.lang.Object{
      public test.Animal();
        Code:
         0:   aload_0
         1:   invokespecial   #8; //Method java/lang/Object."<init>":()V
         4:   return
      
      public void sayHello();
        Code:
         0:   getstatic   #15; //Field java/lang/System.out:Ljava/io/PrintStream;
         3:   ldc #21; //String Hello !!
         5:   invokevirtual   #23; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8:   return
      
      public static void main(java.lang.String[]);
        Code:
         0:   new #31; //class test/Dog
         3:   dup
         4:   invokespecial   #33; //Method test/Dog."<init>":()V
         7:   astore_1
         8:   aload_1
         9:   invokevirtual   #34; //Method sayHello:()V
         12:  aload_1
         13:  checkcast   #31; //class test/Dog
         16:  invokevirtual   #36; //Method test/Dog.bark:()V
         19:  return
      
      }
      

      如您所见,这里有一个额外的checkcast,根据此链接解决:

      http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc2.html

      为了避免像块一样的循环延迟: 在循环外投射,然后使用...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-21
        • 2012-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多