cool hit counter What you don't know about equals and ==_Intefrankly

What you don't know about equals and ==

Let's start with an equals and == related interview question.

 What is the output of this java code below? (disregarding older versions of java before 1.5 and line breaks) (- from
publi class HelloWorld{
    public static void main(String[] args){
        Integer i1=127, i2=127, i3=128, i4=128;

First, I'll tell you the answer is true, true, false, and true.

Both i1 == i2 and i1.equals(i2) are true, which most people should be able to answer correctly. The latter i3 == i4 and i3.equals(i4) are probably confusing to a lot of people.

Integer is a wrapper class for the basic data type int, and the conversion between int and Integer is achieved through auto-boxing and auto-unboxing, so the nature of auto-boxing and unboxing has to be understood first.

We can see the process of boxing and unboxing by decompiling the class file.

Write a test class Test with the following code.

public class Test {
    public static void main(String[] args) {
        Integer i1 = 10;
        int i2 = i1;

Here I use the Windows cmd command line to compile the java file into a bytecode file first, and then use jdk's own decompiler tool, javap, to decompile the bytecode file, and the result is shown below.

{% asset_img decompile.png decompile%}

We can see that there are Test The default constructor for the class approach, (located) atmain approach and then separately in the call to Integer class static (as in electrostatic force) approach valuOf() harmony intValue(), So in fact the automatic boxing behind the use of valueOf() approach, Behind the automatic unpacking is the use of intValue() approach。

To understand the problem thoroughly, it is more effective to look at the source code of the Integer class directly than the theory summarized in the book.

public final class Integer extends Number implements Comparable<Integer> {
    public static final int MIN_VALUE = -2147483648;
    public static final int MAX_VALUE = 2147483647;
    private final int value;
    public static final int SIZE = 32;
    public static final int BYTES = 4;
    //  Automatic boxing of valueOf  approach
    public static Integer valueOf(int var0) {
        return var0 >= -128 && var0 <= Integer.IntegerCache.high ? Integer.IntegerCache.cache[var0 + 128] : new Integer(var0);
    //  automated unpacking intValue()  approach
    public int intValue() {
        return this.value;
    // equals  approach
    public boolean equals(Object var1) {
        if (var1 instanceof Integer) {
            return this.value == (Integer)var1;
        } else {
            return false;
    // Integer  class IntegerCache  static class (as in electrostatic force)
    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer[] cache;

        private IntegerCache() {

        static {
            int var0 = 127;
            String var1 = VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            int var2;
            if (var1 != null) {
                try {
                    var2 = Integer.parseInt(var1);
                    var2 = Math.max(var2, 127);
                    var0 = Math.min(var2, 2147483518);
                } catch (NumberFormatException var4) {

            high = var0; #  for high  assign a value to
            cache = new Integer[high - -128 + 1]; # cache  arrays
            var2 = -128;

            for(int var3 = 0; var3 < cache.length; ++var3) {
                cache[var3] = new Integer(var2++);

            assert high >= 127;


From the source code, we can see that the Integer class is modified by the final keyword, that is, the Integer class and String class are not inherited by other classes, and can also see the static constants MAX_VALUE, MIN_VALUE value is the range of the int type, and SIZE, BYTES, which is not the number of bits and bytes occupied by the int type Well! There are other variables defined in the class, so the reader can check and read the source code for themselves.

Automatic boxing of approach valueOf() in is to return a trinomial value, The code is to the effect that, To box value var0 If the -128 up to IntegerCache Class static variables in classes high interval between values, Just return.IntegerCache classes cache arrays The value of the element in, Otherwise use var0 value constructs a Integer targets。 Now the attention shifts to IntegerCache kind, It can be found high The value of the actual127,cache arrays The length of the actual 127 + 128 + 1 even 256, And below is a description of cache arrays initialize assign a value to, through (a gap) -128 up to 127。 Since these codes are wrapped in static in the statement block, So the first time you use Integer chronological, this one cache arrays And it will be set up。 This is actually Java The caching policy in, Similarly. ByteCache、ShortCache、LongCache、CharacterCache kind, Separate cache Byte targets、Short targets、Long targets、Character targets, Readers can view the source code for these classes for themselves, It's all similar.。

automated unpacking approach intValue() It's a little easier., Return directly to the current Integer target group value happen to。

Before we look at the equals method, let's think about why there is an equals method. Yes, the equals method compares two objects to see if they are the same, exactly, we want to use the equals method to determine if the values of two objects are equal, readers who have studied C++ should know that you can overload operators in C++, but have you ever seen overloaded operators in Java? Some attentive readers will say, isn't the + operator in Java? We can splice two strings of type String with + (plus sign). It looks like it is, but readers with some knowledge of Java strings know that it's really just syntactic sugar, and what looks like it is isn't necessarily what it is. You can write a test class that emulates the process of decompiling above by writing two strings and adding them together to see what method is being called behind the scenes. Here's a quick note: the append() method is called by an object of the StringBuilder class behind the + (addition). The reason why Java does not want to overload operators like C++ is because of historical reasons and because operator overloading reduces the readability of the code and is not suitable for maintenance. Personally, I don't think it's a good idea to overload operators directly, but in Python you do it by overloading the methods behind the operators, e.g. if you want to overload the + (plus) operator, you overload add () method, which is much clearer.

The equals() method of the Integer class first determines whether the object to be compared is of the Integer class type, and returns false if it is not. The instanceof keyword is used here to determine whether an object is an instance of a class or interface. If so, the == (double equal sign) operator is used to determine whether the value variables in the two objects are equal, after converting the type of the object to be compared to Integer, of course. The == (double equal sign) is also used in the equals() method in Integer. The equals() method is not that mysterious, it's just a normal method in the class. This method first appeared in Java in the mother-of-all-images Object class and exists to compare two objects to see if they are identical. source public boolean equals(Object obj) {return (this == obj); } is very simple, is the use of equal sign to compare the reference address of the two objects is not equal, subclasses if you want to use this method, overload it, otherwise directly and directly using == (double equal sign) comparison is no difference. And when we override the method in our custom class, we also override the hash() function, the hash value of an object can be seen as the object's ID card, and not much else here.

Here is the metaphysical time, what makes two objects the same? In real life, can two people with the same name say they are the same? The determination of whether it is the same person is based on whether he is a soul or a body or both. If it is thought that the person is judged on the basis of his soul, is the person still this person if his soul is not dead?.

The above question is just simple data type, in Java, == (double equal sign) can compare whether the values of basic data types are equal or not, the following code results in false, true, now you should understand it.

Integer i1 = 127;
Byte b1 = 127;
int i2 = 127;
byte b2 = 127;
System.out.println(i2 == b2);

equals() approach simply put, It's how you see two objects as the same.。 For two strings, If the two strings have the same value, We routinely assume that they are equal, But these two strings could be two objects, philosophically, It's all about how you see the world。

It's here., I intercepted it too. String class equals() approach source code。

public final class String implements Serializable, Comparable<String>, CharSequence {
    private final char[] value;
    public boolean equals(Object var1) {
            if (this == var1) {
                return true;
            } else {
                if (var1 instanceof String) {
                    String var2 = (String)var1;
                    int var3 = this.value.length;
                    if (var3 == var2.value.length) {
                        char[] var4 = this.value;
                        char[] var5 = var2.value;

                        for(int var6 = 0; var3-- != 0; ++var6) {
                            if (var4[var6] != var5[var6]) {
                                return false;

                        return true;

                return false;

(located) at String generic approach in, First determine if the two objects are the same object, If it's the same object, Then the string value must be the same., Direct return true。 If it's not the same object, First determine if the object to be compared is String Example of a class, If it is, Look again at the two objects in the value arrays Is it the same length?, this one value arrays What's in it is naturally every character in the string。 If it's the same length, Just compare the characters again arrays Is each character in the same, If it's all the same, or so equals approach Just return. true。

additionally String class has a very strange approach, The source code is public native String intern();, this one intern() approach There was no realization of the body, On a statement, So where is it implemented?? Modify this approach There is a native Keywords., This keyword indicates that this approach is a native function, That is, this function implementation is not Java written, So if you want to see the source code you have to go to other languages。 Programming areas,JNI(Java Native Interface,Java local interface) It's a programming framework, feasible Java in the virtual machine Java The program can call the local application/ warehouse, And of course it can be called by other programs。Java The underlying virtual machine needs to call the native operating system's programs, These procedures are likely to be C、C++ or written in assembly language,Java The cross-platform nature of this is also dependent on the native operating system on the one hand。

(located) at Java in,String str1 = "abcd"; harmony String str2 = new String("abcd"); Creating objects is not the same, The former is from String The constant pool of the class string takes the object( If you don't have the object, add it before you take it), The latter creates a new object in heap memory, Not much to say here either。 upper intern() approach will find if there are string objects with equal string values in the constant pool, Returns a reference to the string object if it exists, If not, add the string to the constant pool。

Then the answer to the following question would be false, true, false.

String s1 = new String("abcd");
String s2 = "abcd";
String s3 = s2.intern();
System.out.println(s1 == s2);
System.out.println(s2 == s3);
System.out.println(s1 == s3);

When you look at Java source code, you may feel that some parts are written "badly", because foreigners write it, foreigners also have their programming style, naming habits, we have to learn good nutrition from it.

The following two questions, the heart should have a number, it is recommended to go to see the relevant source code Oh.

Character ch1 = new Character('a');
Character ch2 = new Character('a');
Character ch3 = 'b';
Character ch4 = 'b';
char ch5 = 'b';
System.out.println(ch1 == ch2);
System.out.println(ch3 == ch4);
System.out.println(ch3 == ch5);
System.out.println(ch2 == ch3);
System.out.println(ch2 == ch5);

String s1 = "abc";
String s2 = "abc";
String s3 = new String("def");
String s4 = new String("def");
System.out.println(s1 == s2);
System.out.println(s3 == s4);

Not here. for Here's the answer., You can write a program to check。

To conclude. equals() approach and the difference between the double equals sign:

  • equals It's a approach, And the double equal sign is an operator。
  • The return value of the equals method depends on the specific implementation of the method.
  • For basic data types, the double-equal sign is the value being compared, while for class types, the double-equal sign compares whether the references are the same, and here it is important to note the caching policy and constant pool in Java.
  • If the equals() method is not overridden in the class, then the equals() method is the implementation in the parent class Object and compares whether the references are the same.

1、A stern statement about the Ether Coin Purse phishing site
2、Two lessons learned about the use of regular expressions
3、Changhong Announces Worlds First Changhong R8 Kirin
4、Reflecting on 2018 Expository Text Reading Preparation 2019
5、MATLAB Programming Basics Summary

    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送