Unsafe类是一个final类,位于rt.jar包下,是sun公司提供的一个工具类。
这个类提供了执行native方法的能力,首先,官网不推荐我们直接使用Unsafe,原因如它的名字一样,不安全。
为什么不安全呢,因为native方法直接调用操作系统的指令来执行,效率很高,但是不受jvm控制,因此容易出问题。
当然,如果你艺高人胆大,建议剑走偏锋!
但是我们在源码中,经常能看到Unsafe的身影,那么,如何获取Unsafe实例呢?
可以借鉴caffeine的做法。源码如下:
public final class UnsafeAccess {
static final String ANDROID = "THE_ONE";
static final String OPEN_JDK = "theUnsafe";
/** The Unsafe instance. */
public static final Unsafe UNSAFE;
static {
try {
UNSAFE = load(OPEN_JDK, ANDROID);
} catch (Exception e) {
throw new Error("Failed to load sun.misc.Unsafe", e);
}
}
/**
* Returns the location of a given static field.
*
* @param clazz the class containing the field
* @param fieldName the name of the field
* @return the address offset of the field
*/
public static long objectFieldOffset(Class<?> clazz, String fieldName) {
try {
return UNSAFE.objectFieldOffset(clazz.getDeclaredField(fieldName));
} catch (NoSuchFieldException | SecurityException e) {
throw new Error(e);
}
}
static Unsafe load(String openJdk, String android) throws NoSuchMethodException,
InstantiationException, IllegalAccessException, InvocationTargetException {
Field field;
try {
// try OpenJDK field name
field = Unsafe.class.getDeclaredField(openJdk);
} catch (NoSuchFieldException e) {
try {
// try Android field name
field = Unsafe.class.getDeclaredField(android);
} catch (NoSuchFieldException e2) {
// try to create a new instance
Constructor<Unsafe> unsafeConstructor = Unsafe.class.getDeclaredConstructor();
unsafeConstructor.setAccessible(true);
return unsafeConstructor.newInstance();
}
}
field.setAccessible(true);
return (Unsafe) field.get(null);
}
private UnsafeAccess() {}
}
caffeine缓存框架中使用了UnSafe类,广泛使用在各种缓存Map中。感兴趣的朋友,可以研究一下。