Skip to content

Commit 739e230

Browse files
authored
Update unsafe.md
1 parent 2eb3ba9 commit 739e230

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

docs/java/basis/unsafe.md

+43
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,49 @@ public boolean validate(long stamp) {
304304

305305
#### 介绍
306306

307+
**例子**
308+
309+
```java
310+
import sun.misc.Unsafe;
311+
import java.lang.reflect.Field;
312+
313+
public class Main {
314+
315+
private int value;
316+
317+
public static void main(String[] args) throws Exception{
318+
Unsafe unsafe = reflectGetUnsafe();
319+
assert unsafe != null;
320+
long offset = unsafe.objectFieldOffset(Main.class.getDeclaredField("value"));
321+
Main main = new Main();
322+
System.out.println("value before putInt: " + main.value);
323+
unsafe.putInt(main, offset, 42);
324+
System.out.println("value after putInt: " + main.value);
325+
System.out.println("value after putInt: " + unsafe.getInt(main, offset));
326+
}
327+
328+
private static Unsafe reflectGetUnsafe() {
329+
try {
330+
Field field = Unsafe.class.getDeclaredField("theUnsafe");
331+
field.setAccessible(true);
332+
return (Unsafe) field.get(null);
333+
} catch (Exception e) {
334+
e.printStackTrace();
335+
return null;
336+
}
337+
}
338+
339+
}
340+
```
341+
342+
输出结果:
343+
344+
```
345+
value before putInt: 0
346+
value after putInt: 42
347+
value after putInt: 42
348+
```
349+
307350
**对象属性**
308351

309352
对象成员属性的内存偏移量获取,以及字段属性值的修改,在上面的例子中我们已经测试过了。除了前面的`putInt``getInt`方法外,Unsafe 提供了全部 8 种基础数据类型以及`Object``put``get`方法,并且所有的`put`方法都可以越过访问权限,直接修改内存中的数据。阅读 openJDK 源码中的注释发现,基础数据类型和`Object`的读写稍有不同,基础数据类型是直接操作的属性值(`value`),而`Object`的操作则是基于引用值(`reference value`)。下面是`Object`的读写方法:

0 commit comments

Comments
 (0)