In general, in Kotlin, == compares whether numeric values are equal, while === compares whether the addresses of two objects are equal.

Code1:

val a: Int = 999
val b: Int? = a
val c: Int? = a
println(b == c)    //true
println(b === c)   //false
Copy the code

This is not surprising in Java, where == compares values and === compares addresses, the former true and the latter false.

Code1 corresponds to the Java code:

short a = 999;
Integer b = Integer.valueOf(a);
Integer c = Integer.valueOf(a);
boolean var4 = Intrinsics.areEqual(b, c);
System.out.println(var4);
var4 = b == c;
System.out.println(var4);
Copy the code

Look at the following code in action.

Code2:

 val a: Int = 999
 val b: Int = a
 val c: Int = a
 println(b == c)     // true
 println(b === c)    // true
Copy the code

The difference between this code and the first code is Int and Int, okay? Why is the result of === = different? Don’t worry, look at this code again

Code3:

val a: Int? = 999
val b: Int? = a
val c: Int? = a
println(b == c)    //true
println(b === c)   //true
Copy the code

Code3 corresponds to Java code:

Integer a = Integer.valueOf(999);
boolean var4 = Intrinsics.areEqual(a, a);
System.out.println(var4);
var4 = a == a;
System.out.println(var4);
Copy the code

The difference between code3 code and code1 code is the Int in the first line. Int === true; Int == true;

The following is the best explanation for the above phenomenon

Note that on the Java platform, values are physically stored by the JVM as bytecode, unless we need to make nullable identifiers (such as Int?). Or generics. In the latter numerical is packing (see http://www.kotlindoc.cn/Basics/Basic-Types.html) this article.

So if we use val a: Int = 999, then a is just a number, not an object, not an object, but if we use val a: Int, right? = 999, in this case, a is an Int object, which is involved in the boxing problem, which explains why the first code is false because a is a number, and B and C are boxed objects, and the second code is a, B, and C are all numbers, and the third code is a, B, C is the same object

Now let’s do a special case

Code4:

val a: Int = 100
val b: Int? = a
val c: Int? = a
println(b == c)    //true
println(b === c)   //true   
Copy the code

Code4 corresponding Java code:

 byte a = 100;
 Integer b = Integer.valueOf(a);
 Integer c = Integer.valueOf(a);
 boolean var4 = Intrinsics.areEqual(b, c);
 System.out.println(var4);
 var4 = b == c;
 System.out.println(var4);
Copy the code

Code4 code and Code1 code are strange! In addition to the value is not the same accident corresponding Java source code is similar, the source code is only the value type is not the same, the reason is only possible, we continue to look at the source code of valueOf:

public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
}


private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if(integerCacheHighPropValue ! =null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache(a) {}}Copy the code

Values between -128 and 127 are not repackaged as new objects, but instead use data cached in the IntegerCache, so the addresses and values of b and C are the same object.