Arguments and parameters
public int sum(int x,int y) {
return x+y;
}
sum(2,3);
复制代码
Code above sum () method of the x, y is the parameter, the method invokes sum (2,3) 2 and 3 is the argument. Parameter in the method definition stage, but the argument is really a method call stage.
View bytecode
The basic parameters of the type of call
private static int intStatic = 222;
public static void main(String[] args) {
method(intStatic);
System.out.println(intStatic);
}
public static void method(int intStatic) {
intStatic = 777;
}
复制代码
Bytecode above method () method ( javap -verbose XXX.class
) as follows:
public static void method(int);
descriptor: (I)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: sipush 777
3: istore_0
4: return
LineNumberTable:
line 13: 0
line 14: 4
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 intStatic I
复制代码
sipush: shaping a short constant value to the stack pushed
The form -1-5 iconst int stack bipush push one-byte shows a constant value (-128-127) to the stack pushed sipush represents a short integer constant value (-32768-32767) are pushed to stack
istore_0: The top of the stack int type value into a local variable first.
The above means that the byte code 777 is pushed to the stack, and then assign it to the local variable intStatic. So the results of our output is 222, because the assignment () method is the assignment of a local variable, does not change the value of the static variable, which is the Java variable of the principle of proximity, of course, can be used in such a way Class.intStatic display statement .
Immutable object parameter called
private static String stringStatic = "old string";
public static void main(String[] args) {
method(stringStatic);
System.out.println(stringStatic);
}
public static void method(String stringStatic) {
stringStatic = "new string";
}
复制代码
The above results are output old string
, the same look decompile bytecode
Constant pool:
#6 = String #35 // new string
#7 = String #36 // old string
#10 = Utf8 stringStatic
#35 = Utf8 new string
#36 = Utf8 old string
public static void method(java.lang.String);
descriptor: (Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: ldc #6 // String new string
2: astore_0
3: return
LocalVariableTable:
Start Length Slot Name Signature
0 4 0 stringStatic Ljava/lang/String;
复制代码
ldc: The int, float, or a String constant value from the constant pool are pushed to the stack. astore_0: The top of the stack-type reference value stored in the first local variable.
It means that the byte code value # 6 (reference symbol) pushed to the stack, and assigning that value to the first reference type local variable (stringStatic).
Here you can see # 6 represents the data type is a String, which points to a constant pool CONSTANT_Utf8_info (abbreviation Utf8, Class method field file needs to be referenced to describe the so name) type, this constant represents the class (or interface) the fully qualified name, running time, the JVM based on the fully qualified name of the instance of the class, references to symbols that time is converted to a direct reference (the address is in memory).
Runtime constant pool
The above has been said constant pool, then the constant pool in the end is what stuff?
We all know that the method area and the Java heap, as each thread is a shared memory area, which is used to store class information has been loaded in the virtual machine, constants, static variables, the time compiler to compile code. Class file versions in addition to the classes, fields, methods, and interface description information, there is a constant pool (Constant Pool Table), and for storing various literal reference symbol generated compile, this part will after loading into the operating method of the class time constant pool storage area. Another important feature of the runtime constant pool file relative to Class constant pool is equipped dynamic, Java language does not require constant necessarily produce only compiler, that is not preset the content Class file constant pool to enter the zone method runtime constant pool can also be the new constants into the pool during the operation, String.intern () method is a typical representative.
Generation and permanent method area, a lot of people will be confused. The method area is JVM specification, merely substituting permanently achieved. JDK7 start from constant pool has been moved from the stack to the method area
Text string, declared as a final constant value are literal, and the symbol references a fully qualified name of the following three classes and interfaces constants 1. 2. The field names and descriptors 3. The method of descriptors and name
Constant pool:
#1 = Methodref #9.#28 // java/lang/Object."<init>":()V
#2 = Fieldref #8.#29 // com/generalthink/kafka/ParamDemo.stringStatic:Ljava/lang/String;
#3 = Methodref #8.#30 // com/generalthink/kafka/ParamDemo.method:(Ljava/lang/String;)V
#8 = Class #37 // com/generalthink/kafka/ParamDemo
复制代码
Therefore, the compiler symbol references stringStatic and literal old string will be added to the constant pool Class file, and then type the loading phase, the two constants will enter the runtime constant pool.
Object variable parameter called
The above parameters passed are immutable objects, here again become our next target variable analysis
private static StringBuilder stringBuilderStatic = new StringBuilder("old stringBuilder");
public static void main(String[] args) {
method(stringBuilderStatic);
System.out.println(stringBuilderStatic);
}
public static void method(StringBuilder stringBuilderStaticParam) {
stringBuilderStaticParam.append(" first append");
stringBuilderStaticParam = new StringBuilder("new stringBuilder");
stringBuilderStaticParam.append(" new method's append");
}
复制代码
View keywords corresponding code section as follows:
Constant pool:
#6 = String #41 // first append
#8 = Class #43 // java/lang/StringBuilder
#9 = String #44 // new stringBuilder
#11 = String #46 // new method's append
#12 = String #47 // old stringBuilder
#15 = Utf8 stringBuilderStatic
#30 = Utf8 stringBuilderStaticParam
#41 = Utf8 first append
#43 = Utf8 java/lang/StringBuilder
#44 = Utf8 new stringBuilder
#46 = Utf8 new method's append
#47 = Utf8 old stringBuilder
public static void method(java.lang.StringBuilder);
descriptor: (Ljava/lang/StringBuilder;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: ldc #6 // String first append
3: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
6: pop
7: new #8 // class java/lang/StringBuilder
10: dup
11: ldc #9 // String new stringBuilder
13: invokespecial #10 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
16: astore_0
17: aload_0
18: ldc #11 // String new method's append
20: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
23: pop
24: return
LocalVariableTable:
Start Length Slot Name Signature
0 25 0 stringBuilderStaticParam Ljava/lang/StringBuilder;
复制代码
aload_0: The first local reference type variable pushed to the stack. ldc: The int, float, or a String constant value from the constant pool are pushed to the stack. invokevirtual: Some examples for invoking methods require special handling, including instance initialization method, and a parent private methods Method pop: pop the top of the stack value (not a long or double type) new: create an object, and a reference value onto stack dup: replication and copy the value of the stack values onto the stack astore_0: the top of the stack a first reference value in a local type variable return: return void from the current methods
Note that the aload_0 0 refers to LocalVariableTable
the slot 0 of the parameter, referred to herein as the stringBuilderStaticParam. It is to refer to a static variable is assigned to the local variable table virtual machine stack frame.
The above means that bytecode stringBuilderStaticParam pushed to the stack, and then pushing the first append a constant value to the stack, the method calls StringBuilder.append results obtained, and finally the stack. Then a new StringBuilder, a copy of the return address onto stack, then this address into stringBuilderStaticParam. Aload then re-stack the operation (the value here has been the overwriting, subsequent append operation for a static variable of the class stringBuilderStaticParam stringBuilderStatic nothing), then followed by calling the append method, and finally returns void.
Note that stringBuilderStatic just a pointer to a pointer to a specific address in memory only, it is not the memory address. java spec declared that everything in java is passed by value , this stuff never passed by reference code is the sole criterion for testing finishing, now assumed to be passed by reference, then the execution method after method, the result should be the output new stringBuilder new method's append
, but the result is not output, so the argument passed is passed by value, this value is a pointer to the object only.
How this is done
int m = 1;
public static void main(String[] args) {
ParamDemo demo = new ParamDemo();
System.out.println(demo.method());
}
public int method() {
return m + 1;
}
复制代码
We call method () method in the m, here implicitly uses this, in fact, is this.m. So how this formula to achieve it?
public int method();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: getfield #2 // Field m:I
4: iconst_1
5: iadd
6: ireturn
LineNumberTable:
line 15: 0
LocalVariableTable:
Start Length Slot Name Signature
0 7 0 this Lcom/generalthink/kafka/ParamDemo;
}
复制代码
We LocalVariableTable can be found this to be an argument, its implementation is so simple, Javac compiler compile time to visit this keyword into a common access method parameters, then automatically invoked when a virtual machine instance method this parameter is passed.
When it comes to this certainly think of super, super is actually an ordinary method call, implemented by invokespecial instructions.
String.intern () principle
When using intern () method you think is the role of the dynamic method of adding running literal constants pool. If the runtime constant pool of the same string already exists (the equals method determination), the object pool is returned, otherwise the corresponding reference after it is added to the constant pool.
String s1 = "Hello";
String s2 = new String("Hello").intern();
//true
System.out.println(s1 == s2);
复制代码
The output is true, during compilation "Hello" the literal has been added to the constant pool, during operation, called intern () method, is determined to equal two strings according to the equals method, which then returns a reference constant pool of addresses Hello, so in this case s1, s2 in fact pointing to the same address.
We will modify the code to do something
String s1 = "Hello";
String s2 = "World";
String s3 = s1 + s2;
String s4 = "Hello" + "World";
System.out.println(s3 == s4);
System.out.println(s3.intern() == s4);
复制代码
The results are output to false and true. We note that most of the different s3 and s4 is, s3 is obtained by adding a variable, the same view bytecode
#2 = String #37 // Hello
#3 = String #38 // World
#4 = Class #39 // java/lang/StringBuilder
#5 = Methodref #4.#36 // java/lang/StringBuilder."<init>":()V
#6 = Methodref #4.#40 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#7 = Methodref #4.#41 // java/lang/StringBuilder.toString:()Ljava/lang/String;
#8 = String #42 // HelloWorld
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=5, args_size=1
0: ldc #2 // String Hello
2: astore_1
3: ldc #3 // String World
5: astore_2
6: new #4 // class java/lang/StringBuilder
9: dup
10: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: ldc #8 // String HelloWorld
27: astore 4
...
复制代码
It can be seen from the bytecode actually called StringBuilder.Append s3 () method to get, the value of s4 can be directly determined at compile time, it is an accurate value, so in this case the constant pool HelloWorld in it existed.