Unsafe是Java内部API,外部是禁止调用的,在编译Java类时如果检测到引用了Unsafe类也会有禁止使用的警告:Unsafe是内部专用 API, 可能会在未来发行版中删除
    sun.misc.Unsafe代码片段:

    1. import sun.reflect.CallerSensitive;
    2. import sun.reflect.Reflection;
    3. public final class Unsafe {
    4. private static final Unsafe theUnsafe;
    5. static {
    6. theUnsafe = new Unsafe();
    7. 省去其他代码......
    8. }
    9. private Unsafe() {
    10. }
    11. @CallerSensitive
    12. public static Unsafe getUnsafe() {
    13. Class var0 = Reflection.getCallerClass();
    14. if (var0.getClassLoader() != null) {
    15. throw new SecurityException("Unsafe");
    16. } else {
    17. return theUnsafe;
    18. }
    19. }
    20. 省去其他代码......
    21. }

    由上代码片段可以看到,Unsafe类是一个不能被继承的类且不能直接通过new的方式创建Unsafe类实例,如果通过getUnsafe方法获取Unsafe实例还会检查类加载器,默认只允许Bootstrap Classloader调用。
    既然无法直接通过Unsafe.getUnsafe()的方式调用,那么可以使用反射的方式去获取Unsafe类实例。
    反射获取Unsafe类实例代码片段:

    1. // 反射获取Unsafe的theUnsafe成员变量
    2. Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
    3. // 反射设置theUnsafe访问权限
    4. theUnsafeField.setAccessible(true);
    5. // 反射获取theUnsafe成员变量值
    6. Unsafe unsafe = (Unsafe) theUnsafeField.get(null);

    当然我们也可以用反射创建Unsafe类实例的方式去获取Unsafe对象:

    1. // 获取Unsafe无参构造方法
    2. Constructor constructor = Unsafe.class.getDeclaredConstructor();
    3. // 修改构造方法访问权限
    4. constructor.setAccessible(true);
    5. // 反射创建Unsafe类实例,等价于 Unsafe unsafe1 = new Unsafe();
    6. Unsafe unsafe1 = (Unsafe) constructor.newInstance();

    获取到了Unsafe对象我们就可以调用内部的方法了。