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 }
输出结果:
原始值
修改值
大王让我来巡山