Unsafe初体验

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章