sun.misc.Unsafe的几个点_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > sun.misc.Unsafe的几个点

sun.misc.Unsafe的几个点

 2014/9/14 0:57:54  jnullpointer  程序员俱乐部  我要评论(0)
  • 摘要:一.获取Unsafe,通用的办法利用反射机制FieldunsafeField=Unsafe.class.getDeclaredField("theUnsafe");unsafeField.setAccessible(true);Unsafeunsafe=(Unsafe)unsafeField.get(null);二.Unsafe自己对调用者的检查publicstaticUnsafegetUnsafe(){Classcc=sun.reflect.Reflection.getCallerClass
  • 标签:Sun
一.获取Unsafe,通用的办法利用反射机制
class="java" name="code">
    Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
    unsafeField.setAccessible(true);
    Unsafe unsafe = (Unsafe) unsafeField.get(null);


二.Unsafe自己对调用者的检查
    public static Unsafe getUnsafe() {
        Class cc = sun.reflect.Reflection.getCallerClass(2);
        if (cc.getClassLoader() != null)
            throw new SecurityException("Unsafe");
        return theUnsafe;
}

getCallerClass调用栈帧,从0开始。
0:getCallerClass方法的Reflection类;
1:getUnsafe方法的Unsafe类;
2:调用getUnsafe方法的所属类
比如:
   public static void main(String[] args) throws Exception {
         Class cc = sun.reflect.Reflection.getCallerClass(1); 
         //0:getCallerClass方法的Reflection类,1:main方法的所属类
    }

cc.getClassLoader()!= null 用于判断类加载器是否是bootstrap classloader。
1.Bootstrap ClassLoader - GetClassLoader的返回值为Null,是JVM的C++源码,Ext ClassLoader 的Parent,主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作;
2.System ClassLoader -  GetClassLoader返回值为SystemClassLoader.
主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作
3.Ext ClassLoader - 是AppClassLoader 的Parent 返回Ext ClassLoader 
主要负责jdk_home/lib/ext目录下的jar包或-Djava.ext.dirs 指定目录下的jar包装入工作。
4.App ClassLoader - 返回AppClassLoader,主要负责加载用户类。
(后续在继续分析ClassLoader机制)

三:public native int getInt(Object o, long offset);注释中提到三种情况
第一种场景:The offset was obtained from {@link #objectFieldOffset} on the {@link java.lang.reflect.Field} of some Java field and the object referred to by <code>o</code> is of a class compatible with that field's class.
    private int offset = 10;
    public static void main(String[] args) throws Exception {
        long fieldOffset = unsafe.objectFieldOffset(Main.class.getDeclaredField("offset")) ;
        int fieldValue = unsafe.getInt(new Main(), fieldOffset);
    }


第二种场景:The offset and object reference <code>o</code> (either null or non-null) were both obtained via{@link #staticFieldOffset}  and {@link #staticFieldBase} (respectively) from the reflective {@link Field} representation of some Java field.
    private static int staticoffset = 20;
    public static void main(String[] args) throws Exception {
        Field staticField = Main.class.getDeclaredField("staticoffset");
        long staticFieldOffset = unsafe.staticFieldOffset(staticField);
        Object obj = unsafe.staticFieldBase(staticField);
        int staticFieldValue =unsafe.getInt(obj, staticFieldOffset);
    }

第三种场景:The object referred to by <code>o</code> is an array, and the offset is an integer of the form <code>B+N*S</code>, where <code>N</code> is a valid index into the array, and <code>B</code> and <code>S</code> are the values obtained by {@link #arrayBaseOffset} and {@link #arrayIndexScale} (respectively) from the array's class. The value referred to is the <code>N</code><em>th</em> element of the array.
    public static void main(String[] args) throws Exception {
        int [] intarray = new int[3];
        intarray[0] = 10; intarray[1] = 20; intarray[2] = 30;
        int arrayOffset = unsafe.arrayBaseOffset(intarray.getClass());
        int arrayScale = unsafe.arrayIndexScale(intarray.getClass());
        long lg = arrayOffset + 2 * arrayScale;
        int arrayValue = unsafe.getInt(intarray, lg);
    }
发表评论
用户名: 匿名