// the java source code
public class Demo {
private final Object lock = new Object();
public void read() {
synchronized (lock) {
// more code here ...
}
}
}
// the decompiled .class file
public class Demo {
private final Object lock = new Object();
public void read() {
// Why Java compiler add this line? Is the 'read this.lock' redundant?
Object var1 = this.lock;
synchronized(this.lock) {
// more code here ...
}
}
}
Байткод здесь: javap -l -p -s demo.class
Почему компилятор Java добавляет «избыточное чтение» перед «синхронизированным блоком»?
public void read();
descriptor:()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: aload_0
1: getfield #3 // Field lock:Ljava/lang/Object;
4: dup
5: astore_1
6: monitorenter
7: aload_1
8: monitorexit
9: goto 17
12: astore_2
13: aload_1
14: monitorexit
15: aload_2
16: athrow
17: return
Exception table:
from to target type
7 9 12 any
12 15 12 any
LineNumberTable:
line 15: 0
line 16: 7
line 17: 17
LocalVariableTable:
Start Length Slot Name Signature
0 18 0 this Lxechoz/vipshop/com/demo/thread/Demo;
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 12
locals = [ class xechoz/vipshop/com/demo/thread/Demo, class java/lang/Object ]
stack = [ class java/lang/Throwable ]
frame_type = 250 /* chop */
offset_delta = 4
Я думаю, что линия 1: getfield #3 // Field lock:Ljava/lang/Object;
соответствует Object var1 = this.lock;
.
Я знаю, что компилятор оптимизирует код, добавив или удалив некоторый код.
Но, почему компилятор добавить прочитать заявление перед синхронизируются блок.
Зачем это необходимо? Или почему это оптимизация ?
Возможно, стоит проверить код байта напрямую. Декомпилятор может иметь некоторую роль в этом. – Henry