Unsafe實例獲取
Unsafe實例獲取方法getUnsafe() , 返回值是Unsafe的實例。但如果直接調用會拋: Exception in thread "main" java.lang.SecurityException: Unsafe。 其安全校驗代碼如下:
public static Unsafe getUnsafe() {
Class var0 = Reflection.getCallerClass();
if (!VM.isSystemDomainLoader(var0.getClassLoader())) {
throw new SecurityException("Unsafe");
} else {
return theUnsafe;
}
}
不過我們可以使用反射來繞過驗證,獲得unsafe類實例, 因爲unsafe類裏有一個靜態的Unsafe 實例,名稱是"theUnsafe";代碼如下:
public static Unsafe getUnsafe(){
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
return (Unsafe)field.get(null);
} catch (Exception e) {
}
return null;
}
Unsafe使用示例
演示一個簡單例子,使用Unsafe直接給一個實例變量賦值,然後訪問,看值是否正確寫入:
public class UnsafeTest {
private static final Unsafe unsafe;
private static final long valueOffset;
private volatile int value;
static {
try {
unsafe = getUnsafe();
valueOffset = unsafe.objectFieldOffset
(UnsafeTest.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
public void setValue(int value){
unsafe.putInt(this, valueOffset, value);
}
public static void main(String[] args){
UnsafeTest test = new UnsafeTest();
test.setValue(4);
System.out.println("value=" + test.value);
}
public static Unsafe getUnsafe(){
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
return (Unsafe)field.get(null);
} catch (Exception e) {
}
return null;
}
}