Test 1:
Let’s first look at a set of String type comparisons. Without further ado, just enter the code:
public class Test { public static void main(String[] args) { String a = "java book garden"; String b = "java book garden"; String c = new String("java book garden"); String d = new String("java book garden").intern(); if(a == b){ System.out.println("a == b"); }else{ System.out.println("a != b"); } if(a.equals(b)){ System.out.println("a.equals(b)"); }else{ System.out.println("!a.equals(b)"); } if(a == c){ System.out.println("a == c"); }else{ System.out.println("a != c"); } if(a.equals(c)){ System.out.println("a.equals(c)"); }else{ System.out.println("!a.equals(c)"); } if(a == d){ System.out.println("a == d"); }else{ System.out.println("a != d"); } if(a.equals(d)){ System.out.println("a.equals(d)"); }else{ System.out.println("a.equals(d)"); } }}Output result:
a == ba.equals(b)a != ca.equals(c)a == da.equals(d)
Summarize:
Result a == b: When the program is running, it will create a string buffer pool. When String a = "java book garden", "java book garden" is placed in the string buffer pool. When String b = "java book garden" creates a string, the program will first look for objects with the same value in this String buffer pool. Therefore, when b is created, the program finds a with the same value and references the object referenced by a. Therefore, a and b refer to the same object, so a == b.
As a result, a != c:String c = new String("java Book Garden") new a new object, so it is not searched from the String buffer pool, and directly creates a new object. So a != c.
Result a == d : When the intern method is called, if the pool already contains a string equal to this String object (the object is determined by the equals(Object) method), the string in the pool is returned. Otherwise, add this String object to the pool and returns a reference to this String object. All d calls objects of a.
equals compares values, so when the values are the same, they are equal.
Test 2:
Here is a test of a set of int types and Integer types:
public class Test { public static void main(String[] args) { int a = 127; int a1 = 127; int b = 128; integer c = 127; Integer c1 = 127; Integer d = 128; Integer d1 = 128; if(a == a1){ System.out.println("a == a1"); }else{ System.out.println("a != a1"); } if(b == b1){ System.out.println("b == b1"); }else{ System.out.println("b != b1"); } if(c == c1){ System.out.println("c == c1"); }else{ System.out.println("c != c1"); } if(d == d1){ System.out.println("d == d1"); }else{ System.out.println("d != d1"); } }}Output result:
a == a1b == b1c == c1d != d1
The result "a == a1" and "b == b1":int are basic types, and the values are stored directly, while integer is an object, and points to this object with a reference. Most of the comparisons are made of "a == a1" and "b == b1".
The results "c == c1" and "d != d1" may have questions here, why "d != d1". Let's take a look at the source code of Integer together.
/** * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. The size of the cache * may be controlled by the -XX:AutoBoxCacheMax=<size> option. * During VM initialization, java.lang.Integer.IntegerCache.high property * may be set and saved in the private system properties in the * sun.misc.VM class. */ 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) { 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); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} } /** * Returns an {@code Integer} instance representing the specified * {@code int} value. If a new {@code Integer} instance is not * required, this method should generally be used in preference to * the constructor {@link #Integer(int)}, as this method is likely * to yield significantly better space and time performance by * caching frequently requested values. * * This method will always cache values in the range -128 to 127, * inclusive, and may cache other values outside of this range. * * @param i an {@code int} value. * @return an {@code Integer} instance representing {@code i}. * @since 1.5 */ public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }Conclusion: Here Integer will initialize a constant pool of [-128,127]. If the value is in this range, the same object is referenced. If it is not in this range, it can be seen from the source code that the returned new object is: return new Integer(i);
Therefore, the result "c == c1" refers to the same object, and the result "d != d1" refers to new a new object, so it is different.