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

 

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