This article covers some JVM principles and Java bytecode Directives, recommend interested readers to read a classic book on the JVM, Deep Java Virtual Machine (2nd edition), and compare it with the IL assembly directives I described in ". NET 4.0 object-oriented Programming". Believe that readers will have some inspiration. It is one of the most effective learning methods to compare the similarities and differences of two similar things carefully.
In the future, I will also release other articles on personal blog, hoping to help readers of the book to broaden their horizons, inspire thinking, we explore the mysteries of technology.
The content described in this article only represents the understanding of the individual, any omissions and errors, please directly reply to indicate.
1 Peculiar program output
A while ago, a student showed me a "very strange" Java code:
public class Testinteger {
public static void Main (string] args) {
Integer v1=100;
Integer v2=100;
System.out.println (V1==V2); Output: True
Integer w1=200;
Integer w2=200;
System.out.println (W1==W2); Output: false
}
}
What puzzles the student most is why such similar code has such an unexpected output?
I usually use a lot of C#,java, the first time I saw the output of this code, I was also very strange: how can this be? 100 and 200 are the two integer values essentially different to the class of integers?
To understand the underlying cause of the phenomenon, I used the JAVAP tool to disassemble the. class file generated by the Java compiler:
By carefully reading the Java compiler raw byte code, I found the following statement to assign a value to an integer variable:
Integer v1=100;
The Integer.valueof method is actually invoked.
To complete the following statement of two integer variable comparisons:
System.Console.WriteLine (v1 = = v2);
The if_acmpne instruction is actually generated. Where a represents "address", CMP represents "Compare", and NE represents "not equal".
The meaning of this instruction is to compare the two operands in the Java method stack (that is, V1 and v2) to see if they point to the same object in the heap.
When you assign a value of 100 to V1 and V2, they reference the same integer object.
So why is W1 and W2 "turned out" to refer to different integer objects when the shift is changed to 200?
The secret lies in the Integer.valueof method. Fortunately, the Java Class Library is open source, so we can easily see the relevant source code:
public static Integer valueof (int i) {
if (i >= -128 && i <= integercache.high)
Return integercache.cache[i + 128];
Else
return new Integer (i);
}
All the truth, the original integer in the internal use of a private static class Integercache, this class internally encapsulates an integer object cache array to buffer the integer object, the code is as follows:
private Static Class Integercache {
Static final Integer cache[];
......
}
Take a closer look at the code inside the Integercache and see that it uses a static initialization block to hold a total of 256 integer objects in the cache array in the [-128,127] interval.
When you assign an integer value directly to an integer variable, if the value is in [-128,127], the JVM (Java Virtual Machine) directly uses a cached integer object in the cache, otherwise the JVM will re-create an integer object.
All the truth.