Search code examples
scalascala-2.10

Why is Scala's == different in case of Int?


Isn't it supposed to call equals behind the scene?

scala> 1 equals 1l
res2: Boolean = false

scala> 1 == 1l
res3: Boolean = true

Solution

  • as @MichaelLang suggests, this answer can help you, concretely:

    comparing two primitives (boxed or unboxed) with == should always give the result you would have gotten by comparing those values as unboxed primitives. When you call equals directly, you are skipping all that softening logic and instead treated to java's theory that two boxed values of different types are always unequal.

    If you analyze the bytecode:

    1 == 1l produces

             0: aload_0       
             1: invokespecial #19                 // Method java/lang/Object."<init>":()V
             4: aload_0       
             5: putstatic     #21                 // Field MODULE$:L;
             8: aload_0       
             9: iconst_1      
            10: putfield      #17                 // Field res0:Z
            13: return        
    

    directly compares the values of both primitive 1's, but if you examine:

    1 equals 1l then

         0: aload_0       
         1: invokespecial #19                 // Method java/lang/Object."<init>":()V
         4: aload_0       
         5: putstatic     #21                 // Field MODULE$:L;
         8: aload_0       
         9: iconst_1      
        10: invokestatic  #27                 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
        13: lconst_1      
        14: invokestatic  #31                 // Method scala/runtime/BoxesRunTime.boxToLong:(J)Ljava/lang/Long;
        17: invokevirtual #35                 // Method java/lang/Object.equals:(Ljava/lang/Object;)Z
        20: putfield      #17                 // Field res0:Z
        23: return      
    

    Where you can see that is boxing 1l primitive into a Long object and then performing the equals.