Unsafe
程序员文章站
2022-06-23 14:20:56
...
[align=center][size=large]Unsafe[/size][/align]
一、总结
1.jdk 1.8.0
2.不可仿照 AtomicInteger 的方式直接调用 Unfase
3.从源码注释得知,这个类是用于执行低级别、不安全操作的方法集合。尽管这个类和所有的方法都是公开的(public),但是这个类的使用仍然受限,你无法在自己的java程序中直接使用该类,因为只有授信的代码才能获得该类的实例。所以我们平时的代码是无法使用这个类的,因为其设计的操作过于偏底层,如若操作不慎可能会带来很大的灾难,所以直接禁止普通代码的访问,当然JDK使用是没有问题的。
二、源码分析
博文参考:
[url=http://blog.csdn.net/aitangyong/article/details/46439375]java对象的内存布局(二):利用sun.misc.Unsafe获取类字段的偏移地址和读取字段的值[/url]
[url=http://blog.csdn.net/zhangerqing/article/details/43057799]Java之美[从菜鸟到高手演练]之atomic包的原理及分析[/url]
一、总结
1.jdk 1.8.0
2.不可仿照 AtomicInteger 的方式直接调用 Unfase
// 声明全局的静态变量,运行时会出现异常 SecurityException("Unsafe")
private static final Unsafe unsafe = Unsafe.getUnsafe();
3.从源码注释得知,这个类是用于执行低级别、不安全操作的方法集合。尽管这个类和所有的方法都是公开的(public),但是这个类的使用仍然受限,你无法在自己的java程序中直接使用该类,因为只有授信的代码才能获得该类的实例。所以我们平时的代码是无法使用这个类的,因为其设计的操作过于偏底层,如若操作不慎可能会带来很大的灾难,所以直接禁止普通代码的访问,当然JDK使用是没有问题的。
二、源码分析
// 获取类中属性在对象中的地址的偏移量,即以堆中开辟的对象空间的起始地址为基址
// 相对于此值的偏移地址;根据对象的起始位置和偏移量可确认该属性在堆中的存放位置
// 进而可以获取到此属性的值
public native long objectFieldOffset(Field field);
// 示例
// 通过获取类中属性的偏移量,配合对象的地址,获取该属性的值
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class ObjectMain {
private int a ;
private int b ;
private String str ;
/**
* @param args
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Unsafe unsafe = getUnsafeInstance();
// 获取实例字段的偏移地址,偏移最小的那个字段(仅挨着头部)就是对象头的大小
long objectFieldOffseta = unsafe.objectFieldOffset(ObjectMain.class.getDeclaredField("a"));
long objectFieldOffsetb = unsafe.objectFieldOffset(ObjectMain.class.getDeclaredField("b"));
System.out.println(objectFieldOffseta);
System.out.println(objectFieldOffsetb);
// 通过偏移量和对象的基址
ObjectMain main = new ObjectMain();
main.setA(10);
Integer resultA = unsafe.getInt(main,objectFieldOffseta);
System.out.println(resultA);
}
/**
* 通过反射获取Unsafe类中 theUnsafe 属性
* @return
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
private static Unsafe getUnsafeInstance() throws SecurityException, NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
return (Unsafe) theUnsafeInstance.get(Unsafe.class);
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
public static Unsafe getUnsafe()
{
Class class1 = Reflection.getCallerClass();
if(!VM.isSystemDomainLoader(class1.getClassLoader()))
throw new SecurityException("Unsafe");
else
return theUnsafe;
}
private static final Unsafe theUnsafe;
static
{
registerNatives();
Reflection.registerMethodsToFilter(sun/misc/Unsafe, new String[] {
"getUnsafe"
});
theUnsafe = new Unsafe();
}
private static native void registerNatives();
博文参考:
[url=http://blog.csdn.net/aitangyong/article/details/46439375]java对象的内存布局(二):利用sun.misc.Unsafe获取类字段的偏移地址和读取字段的值[/url]
[url=http://blog.csdn.net/zhangerqing/article/details/43057799]Java之美[从菜鸟到高手演练]之atomic包的原理及分析[/url]
上一篇: Java中的Unsafe
下一篇: VR游戏价格过高 原因是过于小众吗?
推荐阅读
-
Unsafe的用法
-
MySQL:Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEM
-
Java中unsafe操作实例总结
-
Java并发编程学习之Unsafe类与LockSupport类源码详析
-
Java中的魔法类:sun.misc.Unsafe示例详解
-
简单谈一谈Java中的Unsafe类
-
一篇看懂Java中的Unsafe类
-
Java并发编程学习之Unsafe类与LockSupport类源码详析
-
简单谈一谈Java中的Unsafe类
-
Java中的魔法类:sun.misc.Unsafe示例详解