Java魔法类:Unsafe应用解析

发布时间:2023-09-29 14:00

Java魔法类:Unsafe应用解析

Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得Java这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重

注:本文对sun.misc.Unsafe公共API功能及相关应用场景进行介绍。基本介绍如下Unsafe源码所示,Unsafe类为一单例实现,提供静态方法getUnsafe获取Unsafe实例,当且仅当调用getUnsafe方法的类为引导类加载器所加载时才合法,否则抛出SecurityException异常。

一:基本介绍

如下Unsafe源码所示,Unsafe类为一单例实现,提供静态方法 getUnsafe获取Unsafe实例,当且仅当调用getUnsafe方法的类引导类加载器所加载时才合法,否则抛出SecurityException异常。

public final class Unsafe {
  // 单例对象
  private static final Unsafe theUnsafe;

  private Unsafe() {
  }
  @CallerSensitive
  public static Unsafe getUnsafe() {
    Class var0 = Reflection.getCallerClass();
    // 仅在引导类加载器`BootstrapClassLoader`加载时才合法
    if(!VM.isSystemDomainLoader(var0.getClassLoader())) {    
      throw new SecurityException("Unsafe");
    } else {
      return theUnsafe;
    }
  }
}

那如若想使用这个类,该如何获取其实例?有如下两个可行方案。

  • 其一,从getUnsafe方法的使用限制条件出发,通过Java命令行命令-Xbootclasspath/a把调用Unsafe相关方法的类A所在jar包路径追加到默认的bootstrap路径中,使得A被引导类加载器加载,从而通过Unsafe.getUnsafe方法安全的获取Unsafe实例。

    java -Xbootclasspath/a: ${path}   // 其中path为调用Unsafe相关方法的类所在jar包路径
  • 其二,通过反射获取单例对象theUnsafe

    private static Unsafe reflectGetUnsafe() {
      try {
        // Unsafe类有个成员变量:private static final Unsafe theUnsafe
        Field field = Unsafe.class.getDeclaredField("theUnsafe");
        field.setAccessible(true);
        return (Unsafe) field.get(null);
      } catch (Exception e) {
        log.error(e.getMessage(), e);
        return null;
      }
    }

    或者:先获取Class对象,再通过构造器创建Unsafe对象

    // 通过反射获得Unsafe对象
    Class unsafeClass = Unsafe.class;
    // 获得构造函数,Unsafe的构造函数为私有的
    Constructor constructor = unsafeClass.getDeclaredConstructor();
    // 设置为允许访问私有内容
    constructor.setAccessible(true);
    // 创建Unsafe对象
    Unsafe unsafe = (Unsafe) constructor.newInstance();

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号