一、主要方法
* 获取一个实例化对象,但不调用构造函数(Unsafe): public Object allocateInstance(Class<?> cls){}
* 具体流程
/**
* 得到Unsafe实例,因为Unsafe类中只有私有变量,私有构造方法,没有静态的方法来获取变量,所以要使用反射。
* private Unsafe() {}
* private static final Unsafe theUnsafe = new Unsafe();
* 1、Unsafe 类
* 2、获取(getDeclaredField)其中的静态变量theUnsafe
* 3、得到(get)变量的值
*/
/**
*Unsafe中的重点方法
*分配一个实例,但不运行任何构造函数。
*如果尚未初始化该类,则将其初始化。
*/
@ForceInline
public Object allocateInstance(Class<?> cls)
throws InstantiationException {
return theInternalUnsafe.allocateInstance(cls);
}
二、完整代码
package reflect.classhandle;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
/**
* 利用Unsafe绕过JVM对象管理,获取实例
*
* 获取一个实例化对象,但不调用构造函数(Unsafe): public Object allocateInstance(Class<?> cls){}
* <p>
*
* @ClassName: UnsafeDome
* @Author: Xlu
* @Date: 2020-06-14 14:15
* @Version 11
**/
public class UnsafeDome {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
/**
* 得到Unsafe实例,因为Unsafe类中只有私有变量,私有构造方法,没有静态的方法来获取变量,所以要使用反射。
* private Unsafe() {}
* private static final Unsafe theUnsafe = new Unsafe();
* 1、Unsafe 类
* 2、获取(getDeclaredField)其中的静态变量theUnsafe
* 3、得到(get)变量的值
*/
Class<?> cls = Class.forName("sun.misc.Unsafe");
Field theUnsafe = cls.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);
//利用Unsafe实例获取一个单例实例化对象
Class clsSingl=Class.forName("reflect.classhandle.SingletonUnsafe");
SingletonUnsafe singletonDome = (SingletonUnsafe) unsafe.allocateInstance(clsSingl);
//利用单例对象
singletonDome.send();
}
}
class SingletonUnsafe {
private SingletonUnsafe theSingleton=new SingletonUnsafe();
private SingletonUnsafe() {
}
public void send() {
System.out.println("说");
}
}