java - equals 中相同的多个向下转型;它们会被优化吗?

标签 java equals downcast

我倾向于用 Java 编写 equals 方法作为一个衬垫......

class Test {
   private String a = "";
   private Integer b = Integer.MIN_VALUE;
   private Long c = Long.MIN_VALUE;

   public Test(final String a, final Integer b, final Long c) {
       this.a = a;
       this.b = b;
       this.c = c;
   }

   @Override
   public boolean equals(final Object obj) {
        return obj instanceof Test && ((Test) obj).a.equals(this.a)
          && ((Test) obj).b.equals(this.b)
          && ((Test) obj).c.equals(this.c);
   }
}

正如您所看到的,在这种方法中,我多次将对象实例向下转换为测试实例。我的问题是,它会被编译器优化吗,这样就会有一个向下转型,而不是三个向下转型,就像我这样编写 equals 方法一样?

 public boolean equals(final Object obj) {
     if (obj instanceof Test) {
         final Test test = (Test) obj;
         return test.a.equals(this.a) && test.b.equals(this.b)
           && test.c.equals(this.c);
     } else {
         return false;
     }
 }

它不是 question 的重复项在评论中,因为我在这里对 equals 方法的实现的简洁性感兴趣(6 行对 3 行),但不以性能下降为代价。在另一个问题中,区别是一行。

最佳答案

当我反编译该类时,我发现Eclipse编译器和javac确实在equals方法中生成了三个checkcast指令,因此没有优化发生。

当由 Hotspot 优化时,hotspot 可能会发现一次强制转换就足够了。

反编译后的字节码:

public boolean equals(java.lang.Object);
   Code:
      0: aload_1
      1: instanceof    #13                 // class sov/Test
      4: ifeq          62
      7: aload_1
      8: checkcast     #13                 // class sov/Test
     11: getfield      #3                  // Field a:Ljava/lang/String;
     14: aload_0
     15: getfield      #3                  // Field a:Ljava/lang/String;
     18: invokevirtual #14                 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     21: ifeq          62
     24: aload_1
     25: checkcast     #13                 // class sov/Test
     28: getfield      #7                  // Field b:Ljava/lang/Integer;
     31: aload_0
     32: getfield      #7                  // Field b:Ljava/lang/Integer;
     35: invokevirtual #15                 // Method java/lang/Integer.equals:(Ljava/lang/Object;)Z
     38: ifeq          62
     41: aload_1
     42: checkcast     #13                 // class sov/Test
     45: getfield      #12                 // Field c:Ljava/lang/Long;
     48: aload_0
     49: getfield      #12                 // Field c:Ljava/lang/Long;
     52: invokevirtual #16                 // Method java/lang/Long.equals:(Ljava/lang/Object;)Z
     55: ifeq          62
     58: iconst_1
     59: goto          63
     62: iconst_0
     63: ireturn

关于java - equals 中相同的多个向下转型;它们会被优化吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32886349/

相关文章:

python - 为什么在 Python 中说 x = x?

python - 在 Python 中覆盖 equals 但仍然具有引用相等性检查

java - 为什么编译器允许我将一个实现类转换为另一个实现类?

c++ - 在 C++ 中安全地重新缩放和向下转换 float

java - 如何比较两个图像边缘描述符?

java - 使用 lambda 和流表达代码块的简洁方法

java - 将整数打印到文本字段区域

java - 从多列中选择最小值

java - 为什么 SparseIntArray.equals(Object) 不起作用?

java - Java中的多态方法返回类型向下转换