1. How to use the == operator
First, let’s look at an interesting piece of code
Integer a = 1000,b=1000;
Integer c = 100,d=100; public void mRun(final String name){ new Runnable() { public void run() { System.out.println(name); } }; }
System.out.println(a==b);
System.out.println(c==d);
If this question If you can come up with the correct answer and understand the principles behind it. It means your basics are okay. If your answers are true and true, your foundation is lacking.
First announce the answer, run the code, we will get false true. We know that == compares the references of two objects. The abcd here are all newly created objects. Logically speaking, false should be entered. This is the interesting thing about this question. Whether it is an interview question or a forum discussion area, this question has a high appearance rate. The principle is actually very simple. Let’s take a look at the Integer.java class and it will become clear.
public static Integer valueOf(int i) { return i >= 128 || i < -128 new Integer(i) : SMALL_VALUES[i + 128]; } /* A cache of instances used by {@link Integer #valueOf(int)} and auto-boxing */ private static final Integer[] SMALL_VALUES = new Integer[256]; static { for (int i = -128; i < 128; i++) { SMALL_VALUES[i + 128] = new Integer(i); } }
When we declare an Integer c = 100;. At this time, an automatic boxing operation will be performed. To put it simply, the basic data type is converted into an Integer object, and the conversion into an Integer object is the valueOf method called. As you can see, -128-127 is cached in Integer. . The official explanation is that small numbers are used more frequently, so in order to optimize performance, the numbers in between are cached. This is why the answers to this question are false and true. When the value of the declared Integer object is between -128-127, it refers to the same object, so the result is true.
2. String
Then look at the code
String s1 = “abc”;
String s2 = “abc”;
String s3 = new String(“abc”);
System.out.println(s1 == s2);
System.out.println(s1 == s3);
Let’s guess the answer to this question again?
According to the syntax of ==, first of all, s1, s2, and s3 are three different objects. Generally speaking, the output will be false. However, the running result of the program is indeed true or false. The second output of false is understandable, but the first output of true is puzzling. We know that some basic types of variables and object reference variables are allocated in the function's stack memory, while new objects and arrays are stored in the heap memory. However, in addition to this, there is an area called the constant pool.
Like we usually think of String s1 = “abc”; the value of a string object declared like this is stored in the constant pool. When we create an object like String s1 = "abc", "abc" is stored in the constant pool (also called the string pool). When we create a reference to String s2 = "abc", the underlying Java layer will give priority to Check whether "abc" exists in the constant pool. If it exists, let s2 point to this value and will not recreate it. If it does not exist in the constant pool, it will be created and added to the pool. That's why the answers are true and false.
3. Final keyword
Let’s look at a piece of code
public void mRun(final String name){ new Runnable() { public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(name); } }.start(); }
I believe you have written a lot of this kind of code. When an inner class accesses a local variable Sometimes, you need to add the final modifier before the local variable, otherwise the compiler will report an error. This is usually what we do. Okay, here comes the second question, why do we need to add the final modifier? I believe that most friends have never thought about this issue. Whenever they use it, they just add it and they have never delved into the principles. This is not advisable for a good programmer. We must not only know what is happening but also why.
Now let’s analyze why we need to add the final keyword. First of all, the life cycle of inner classes is at the member level, while the life cycle of local variables is actually at the method body and so on. In other words, there will be a situation where when the mRun method is executed and the new thread is running, the new thread will sleep for one second. The main thread will continue to execute, mRun is executed, and the name attribute life cycle ends.
After 1 second, Syetem.out.printh(name) is executed. However, at this time, name has expired and is no longer in the memory. In order to prevent this kind of error, Java strictly requires that local variables in inner classes must be modified with the final keyword. After the local variable is modified by final, a copy of the local variable will be kept in the memory. When the inner class accesses it, it is this copy that is actually accessed. This is like extending the life cycle of local variables. After all, it is Java engineers who filled this hole for us in advance, otherwise I don’t know how many friends would worry about internal class local variables.
4. Things about Integer and int
Look at the code below
Integer a = new Integer(1000);
int b = 1000;
Integer c = new Integer(10);
Integer d = new Integer(10);
System.out.println(a == b);
System.out.println(c == d);
This question is a follow-up to the first question. If you can get the answer to this question quickly, So congratulations, you have a more thorough grasp of ==.
——————————————————Dividing line———————————————————————— –
Correct answer: true, false
Many friends will be confused after seeing this answer. Let’s talk about the second one first. According to the first question, doesn’t Integer cache -128-127? Isn't this supposed to be true, but if you look carefully, the Integer here is new by us and is not cached, so the result is false.
Now let’s see why the first one is true again? First of all, the value here is 1000, which definitely has nothing to do with the Integer cache we know. Since it has nothing to do with caching and a is a newly created object, it stands to reason that the input should be false. But note that b here is of type int. When int and Integer are compared ==, Java will automatically unbox the Integer, that is, convert the Integer into an int type, so the value of the int type is compared here, so the result is true.