Unsafe 其他方法介绍

public native long objectFieldOffset(Field f);

获取对象属性的内存地址,参数是对象属性反射的Field

得到这个地址我们就可以获取这个属性的Value,或者修改这个属性了

1 获取这个属性的方法如下

 public native Object getObject(Object o, long offset);

第一个参数是具体的对象,第二个参数是这个对象属性的地址

2 修改这个属性的方法如下

 public native void putObject(Object o, long offset, Object x);

 第一个参数为具体的对象,第二个参数为对象属性的地址,第三个参数是这个属性的新值

也可以通过这个方法修改

public final native boolean compareAndSwapObject(
Object o, long offset, Object expected,Object x);

这个方法是原子更新,成功返回true

第一个参数具体操作的对象,第二个参数要修改对象属性的地址 第三个参数是期望值 第四个是新值

要修改对象属性的值和期望值一样就替换成新值(比较并且替换)

以下是综合例子

 1 public class UnsafeTest {
 2 
 3     public static void main(String[] args) throws Exception {
 4         
 5          Unsafe unsafe = UnsafeUtil.getUnsafe();
 6          
 7          Test test = new Test();
 8          
 9          //反射获取Test对象name属性的Field
10          Field field = Test.class.getDeclaredField("name");
11          
12          //获取Test对象name属性的内存地址(偏移量)
13          long offset = unsafe.objectFieldOffset(field);
14          
15          //根据地址获取值
16          System.out.println(unsafe.getObject(test, offset));
17          
18          //根据地址修改
19          unsafe.putObject(test, offset, "修改值");
20          
21          System.out.println(test.name);
22          
23          //原子修改
24          unsafe.compareAndSwapObject(test, offset, "修改值", "大王让我来巡山");
25          
26          System.out.println(test.name);
27          
28     }
29     
30     static class Test{
31         public String name = "原始值";
32     }
33 }

输出结果:

原始值
修改值
大王让我来巡山

 

posted @ 2017-02-15 16:08  纵横四海1949  阅读(270)  评论(0编辑  收藏  举报