ln("allocateInstance cat--->" + cat);
Foo f = new Foo();
f.setAge(13);
f.setCat(new Cat("ketty", 120));
long ageOffset = unsafe.objectFieldOffset(Foo.class.getDeclaredField("age"));
// 这个offset的属性是一个Cat对象
long catOffset = unsafe.objectFieldOffset(Foo.class.getDeclaredField("cat"));
// 获取静态属性的时候直接用Class对象,用实例对象的话会发生NPE异常
long defaultStringOffset = unsafe.staticFieldOffset(Foo.class.getDeclaredField("defaultString"));
System.out.println("get age=" + unsafe.getInt(f, ageOffset));
System.out.println("get cat=" + unsafe.getObject(f, catOffset));
System.out.println("get defaultString=" + unsafe.getObject(Foo.class, defaultStringOffset));
System.out.println("---------------------");
// 操作内存放入新值
unsafe.putInt(f, ageOffset, 100);
unsafe.putObject(f, catOffset, new Cat("hello", 333));
unsafe.putObject(f, defaultStringOffset, "new default string");
System.out.println("after put then get age=" + unsafe.getInt(f, ageOffset));
System.out.println("after put then get cat=" + unsafe.getObject(f, catOffset));
System.out.println("after put then get defaultString=" + unsafe.getObject(f, defaultStringOffset));
System.out.println("---------------------");
}
程序输出如下:
static...
allocateInstance cat--->Cat{name='null', speed=0}
get age=13
get cat=Cat{name='ketty', speed=120}
get defaultString=default........
---------------------
after put then get age=100
after put then get cat=Cat{name='hello', speed=333}
after put then get defaultString=new default string
---------------------
Unsafe操作数组
数组除了8种基本类型外,还包括Object数组。在Unsafe
类里是通过静态块来获取这些数据。
public void test2() {
// 获取8种基本类型和Object类型数组的基础偏移量,scale相关的可以理解每个类型对应的值所占的大小
// 通过输出信息我们可以看到基础偏移量都是16,scale除Object的是4外,基础数据类型的scale就是相应的字节大小
System.out.println("Unsafe.ARRAY_BOOLEAN_BASE_OFFSET=" + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET);
System.out.println("Unsafe.ARRAY_BOOLEAN_INDEX_SCALE=" + Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
System.out.println("Unsafe.ARRAY_BYTE_BASE_OFFSET=" + Unsafe.ARRAY_BYTE_BASE_OFFSET);
System.out.println("Unsafe.ARRAY_BYTE_INDEX_SCALE=" + Unsafe.ARRAY_BYTE_INDEX_SCALE);
System.out.println("Unsafe.ARRAY_SHORT_BASE_OFFSET=" + Unsafe.ARRAY_SHORT_BASE_OFFSET);
System.out.println("Unsafe.ARRAY_SHORT_INDEX_SCALE=" + Unsafe.ARRAY_SHORT_INDEX_SCALE);
System.out.println("Unsafe.ARRAY_CHAR_BASE_OFFSET=" + Unsafe.ARRAY_CHAR_BASE_OFFSET);
System.out.println("Unsafe.ARRAY_CHAR_INDEX_SCALE=" + Unsafe.ARRAY_CHAR_INDEX_SCALE);
System.out.println("Unsafe.ARRAY_INT_BASE_OFFSET=" + Unsafe.ARRAY_INT_BASE_OFFSET);
System.out.println("Unsafe.ARRAY_INT_INDEX_SCALE=" + Unsafe.ARRAY_INT_INDEX_SCALE);
System.out.println("Unsafe.ARRAY_LONG_BASE_OFFSET=" + Unsafe.ARRAY_LONG_BASE_OFFSET);
System.out.println("Unsafe.ARRAY_LONG_INDEX_SCALE=" + Unsafe.ARRAY_LONG_INDEX_SCALE);
System.out.println("Unsafe.ARRAY_FLOAT_BASE_OFFSET=" + Unsafe.ARRAY_FLOAT_BASE_OFFSET);
System.out.printl