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;
}
}