Constant Folding in java
Why did I write a blog post because I read an analysis of the final keyword yesterday.But there was a problem that was never solved, so I asked the God of knowledge that was previously added to my qq.The first message he sent me back was Constant Fold.As a cinder ape, I immediately queried the concept.This is the first time you have known this concept.God told me a lot.Let me finally understand the concept of constant folding
Instance Resolution
Yesterday, the code that confused me was the following
public static void main(String[] args) { String a = "hello2"; final String b = "hello"; String d = "hello"; String c = b + 2; String e = d + 2; System.out.println((a == c)); System.out.println((a == e)); }
The result of this execution is
true false
I just don't understand why I was the first to return to true?
With that in mind, let's first understand the concept of constant folding.To better understand the code above
constant folding
The concept of constant folding
- Constant folding is a compiler optimization technique.
- Constant collapse mainly means that the process of adding, subtracting, multiplying and dividing constants during compilation is collapsed
For String s1 = "1" + "2";
The compiler will optimize it to String s1 = "12";
"1" and "2" are not visible in the generated byte code at all.
We validate through idea
1. Source File
public static void main(String[] args) { String s1 = "1"+"2"; }
2. After running, idea has an out folder and finds the class file of the above file
public static void main(String[] args) { String s1 = "12"; }
Indeed, as mentioned above, the compiler will optimize for you
Conditions for Constant Folding to occur
- Constant collapse requires an operation between compile-time constants.
- Compile-time constants are constants whose values can be determined at compile time.
- First: Literal quantities are compile-time constants.(Number literal, string literal, etc.)
- Second, simple operations on compile-time constants result in compile-time constants, such as 1+2,'a'+'b'.
- Finally, the basic types and string variables of final s assigned to compiler constants are also compile-time constants.
Raise a chestnut
1.First chestnut
public static void main(String[] args) { String s1="a"+"bc"; String s2="ab"+"c"; System.out.println(s1 == s2); }
Trust everyone knows, output is true
And only one "abc" string object is created and is in the string constant pool.
2. Second chestnut
public static void main(String[] args) { String a = "a"; String bc = "bc"; String s1 = "a" + "bc"; String s2 = a + bc; System.out.println(s1 == s2); }
What about this result?false
s1 is the literal addition of strings, but s2 is the addition of two variables that are not final, so constant folding will not occur.
Instead, it overrides the String class's unique + operator to something like this (jdk1.8)
String s2 = new StringBuilder(a).append(b).toString();
Here toString() generates a new String variable, which obviously returns false when compared with the==operator.
3. Third chestnut
public static void main(String[] args) { final String a = "a"; final String bc = "bc"; String s1 = "a" + "bc"; String s2 = a + bc; System.out.println(s1 == s2); }
The result here is true
Because the basic type and string variables of final assigned by the compiler constant are also compile-time constants
4. Fourth chestnut
public static void main(String[] args) { String x ="a"; final String a = x; final String bc = "bc"; String s1 = "a" + "bc"; String s2 = a + bc; System.out.println(s1 == s2); }
The result here is false
Note here that final variables are neither initialized by compile-time constants nor compiler constants
A here is not a compiler constant
5. Fifth chestnut
public static void main(String[] args) { String x ="a"; final String a = x; final String bc = "bc"; String s1 = "a" + "bc"; String s2 = a + bc; System.out.println(s1 == s2.intern()); }
The result here is true
In fact, if you want to understand the meaning of the intern method, you will understand it.
// A string pool, initially empty, is privately maintained by class strings. 1,A pool of strings, initially empty, is maintained privately by the class String. // If the string already exists in the constant pool, return its reference directly to the constant pool. If not, save its reference to the string constant pool and return it directly. 2,When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. 3,It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.
summary
Now I'm done. Did you know why true printed above?
So.As long as you keep in mind that constant folding mainly means that the compilation-time operations of adding, subtracting, multiplying and dividing constants are collapsed
Follow-up Supplement
It starts with
Instead, overload the String class's unique + operator to something like this
String s2 = new StringBuffer(a).append(b).toString();
To correct this, I now use jdk1.8 to decompile StringBuilder instead of StringBuffer.This needs to be corrected.I also checked.StringBuilder was only available after jdk1.5.