基于openJDK1.8 源码;
Unsafe 类直接可操作内存,对于Java是非常不安全的,所以基于这种考虑jdk做了如下安全措施
- 禁用反射获取Unsafe 类对象,静态块,在class 加载时执行
static {
registerNatives();
sun.reflect.Reflection.registerMethodsToFilter(Unsafe.class, "getUnsafe");
}
- 只能系统类加载器加载,
@CallerSensitive
public static Unsafe getUnsafe() {
//
Class<?> caller = Reflection.getCallerClass();
if (!VM.isSystemDomainLoader(caller.getClassLoader()))
throw new SecurityException("Unsafe");
return theUnsafe;
}
对于Java对象在内存堆中的数据结构为
对象头(包含对象信息), 字段A(对象引用地址)… 字段B(基本类型实际值);
所以字段对于对象头都有一个固定的偏移位置;Unsafe 操作内存对象信息也是基于此原理;
比如:1 设置对象的一个字段值,获取对象的字段值
public native void putInt(Object o, long offset, int x);
public native Object getObject(Object o, long offset);
public native void putObject(Object o, long offset, Object x);
/** @see #getInt(Object, long) */
public native boolean getBoolean(Object o, long offset);
/** @see #putInt(Object, int, int) */
public native void putBoolean(Object o, long offset, boolean x);
/** @see #getInt(Object, long) */
public native byte getByte(Object o, long offset);
/** @see #putInt(Object, int, int) */
public native void putByte(Object o, long offset,