写一个单例模式:
package test.reflect; public class Singleton { private static Singleton s= null; private Singleton() { } public static Singleton getInstance() { if (s == null) { synchronized (Singleton.class) { if (s == null) { s = new Singleton(); } } } return s; } }
这个Singleton类是一个单实例模型,它的构造方法是private修饰的,外部类没有办法通过new来创建它的实例,只能通过调用它的静态方法getIntance来获得实例,并且在多处调用都返回一个实例,再也不创建多余的实例。
我们的客户端如下:
Singleton singleton = Singleton.getInstance(); System.out.println(singleton); //singleton = new Singleton();这是行不通的
打印结果如下:
test.reflect.Singleton@c17164
但是我们怎样通过private的构造方法创建一个实例呢,答案是反射。
反射式java里重要的一个模块,了解反射可以为我们做很多工作。反射的基本原理就是将一个类的字节码映射成一个可以描述这个类的各种信息的Class对象。
下面我们会在客户端加上一些代码:
Singleton singleton = Singleton.getInstance(); System.out.println(singleton); //singleton = new Singleton();这是行不通的 Class<?> clazz = Singleton.class; //Class<?> clazz = Class.forName("test.reflect.Singleton");//这样也行 Constructor<?>[] constructors = clazz.getDeclaredConstructors();//获得声明的构造器 Constructor<?> privateConstructor = constructors[0];//Singleton类只有一个构造器 privateConstructor.setAccessible(true);//设置accessible为true就可以操作它了 Singleton instance = (Singleton) privateConstructor.newInstance(); System.out.println(instance); System.out.println(singleton == instance);
打印结果为:
test.reflect.Singleton@c17164 test.reflect.Singleton@1fb8ee3 false
我们看到了,两次创建的对象是不同的,我们确实通过私有的构造方法创建了一个Singleton类的实例。