Unsafe类是sun.misc包下的类,是单例的。java本身不能对操作系统底层进行操作,但是Unsafe类提供了一些方法可以实现硬件级别的原子操作。
Unsafe类提供一下一些功能:
内存操作:对内存分配、内存装载等
对象字段的定位及修改
线程的挂起与恢复
CAS操作
下面是一个小例子来说明Unsafe类对内存的修改
import java.lang.reflect.Field;
import java.util.Arrays;
import sun.misc.Unsafe;
public class UseUnsafe {
/**通过反射获取Unsafe类*/
public static Unsafe getUnsafe() {
Unsafe unsafe = null;
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
return unsafe;
}
public static void main(String[] args) {
byte[] byteArray = new byte[5];
System.err.println("byte[]数组的初始值: " + Arrays.toString(byteArray));
//获取Unsafe对象
Unsafe unsafe = getUnsafe();
//获取byte[]数组内存中第一个元素的偏移量
int arrayBaseOffset = unsafe.arrayBaseOffset(byte[].class);
System.err.println("byte[]数组内存中第一个元素的偏移量为 " + arrayBaseOffset);
//直接在内存中给byte[]数组元素赋值
unsafe.putByte(byteArray, arrayBaseOffset, (byte)10);
System.err.println("给byte[]数组第1个元素赋值后 : " + Arrays.toString(byteArray));
unsafe.putByte(byteArray, arrayBaseOffset+2, (byte)2);
System.err.println("给byte[]数组第3个元素赋值后 : " + Arrays.toString(byteArray));
}
}
执行结果为:
可见,byte数组确实进行了修改。虽然Oracle官方不推荐使用Unsafe类,但是我们确实可以利用Unsafe类对内存进行一些处理。