单例模式
饿汉式单例:
public class Hungry {
// private byte[] data1 = new byte[1024*1024];
// private byte[] data2 = new byte[1024*1024];
// private byte[] data3 = new byte[1024*1024];
// private byte[] data4 = new byte[1024*1024];
//可能会浪费空间,开辟了空间,却没有使用
private Hungry(){
}
private final static Hungry HUNGRY = new Hungry();
public static Hungry getInstance(){
return HUNGRY;
}
}
public class LazyMan {
private static boolean PASSWORD = false; //(4)
private LazyMan(){
synchronized (LazyMan.class){ //自定义一个变量PASSWORD ,判断是否有反射破解 (4)
if (PASSWORD ==false){
PASSWORD = true;
}else {
throw new RuntimeException("不要试图使用反射破坏异常");
}
}
// synchronized (LazyMan.class){ //加个锁,如果不为null表示已经创建 (2)
// if (lazyMan!=null){ //双重检测锁变成了三重检测锁
// throw new RuntimeException("不要试图使用反射破坏异常");
// }
// }
System.out.println(Thread.currentThread().getName()+"OK");
}
private static LazyMan lazyMan;
// private volatile static LazyMan lazyMan; // volatile 避免指令重排
懒汉式单例:
public static LazyMan getInstance1() {
if(lazyMan==null){ //不加锁 多线程会有问题
lazyMan = new LazyMan(); //不是一个原子性操作
}
return lazyMan;
}
public static LazyMan getInstance2(){
if (lazyMan==null){ //加锁 双重检测锁模式 DCL懒汉式
synchronized (LazyMan.class){
if(lazyMan==null){
lazyMan = new LazyMan(); //不是一个原子性操作
}
}
}
return lazyMan;
}
/*
* 1.分配内存空间
* 2、执行构造方法,初始化对象
* 3、把这个对象指向者个空间
* 123
* 132 A
* B //此时lazyMan还没有完成构造 解决方法:去加volatile
* */
// //反射
public static void main(String[] args) throws Exception { //(0)
// LazyMan instance1 = LazyMan.getInstance2(); //把instance注释,让两个instance都让反射创建 (0)(3)
Field passwords = LazyMan.class.getDeclaredField("PASSWORD"); //去拿值,改掉(5)
passwords.setAccessible(true); //私有权限破坏掉 (5)
Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);//获得空参构造器(0)
declaredConstructor.setAccessible(true); //无视私有构造器 (0)(1)
LazyMan instance1 = declaredConstructor.newInstance(); //反射创建对象instance2 (1)
passwords.set(instance1,false); //(5)结论:道高一尺魔高一丈!
LazyMan instance2 = declaredConstructor.newInstance(); // 都让反射创建(0)(3)
System.out.println(instance1);//(0)
System.out.println(instance2);//(0)
} //(0)
// //多线程并发 这里没有加volatile就会有问题
// public static void main(String[] args) {
// for (int i = 0; i < 10; i++) {
// new Thread(()->{
// LazyMan.getInstance2();
// }).start();
// }
// }
}
匿名内部类:
public class Holder {
private Holder(){ //构造器私有
}
public static Holder getInstance(){
return InnerClass.HOLDER;
}
public static class InnerClass {
public static final Holder HOLDER = new Holder();
}
}
enum:枚举
//enum是什么? 本身也是一个Class类
public enum EnumSingle {
INSTANCE;
public EnumSingle getInstance(){
return INSTANCE;
}
}
class Test{
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
EnumSingle instance1 = EnumSingle.INSTANCE;
Constructor<EnumSingle> declaredConstructor = EnumSingle.class.getDeclaredConstructor(null);
// Constructor<EnumSingle> declaredConstructor =
// EnumSingle.class.getDeclaredConstructor(String.class,int.class);
declaredConstructor.setAccessible(true);
EnumSingle instance3 = declaredConstructor.newInstance();
EnumSingle instance2 = EnumSingle.INSTANCE;
System.out.println(instance1); //显示 java.lang.NoSuchMethodException 没有空参构造方法??
System.out.println(instance2);
System.out.println(instance3);
}
}
newInstance源码:
@CallerSensitive
@ForceInline // to ensure Reflection.getCallerClass optimization
public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
{
Class<?> caller = override ? null : Reflection.getCallerClass();
return newInstanceWithCaller(initargs, !override, caller);
}
/* package-private */
T newInstanceWithCaller(Object[] args, boolean checkAccess, Class<?> caller)
throws InstantiationException, IllegalAccessException,
InvocationTargetException
{
if (checkAccess)
checkAccess(caller, clazz, clazz, modifiers);
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
ConstructorAccessor ca = constructorAccessor; // read volatile
if (ca == null) {
ca = acquireConstructorAccessor();
}
@SuppressWarnings("unchecked")
T inst = (T) ca.newInstance(args);
return inst;
}
* 1.分配内存空间 * 2、执行构造方法,初始化对象 * 3、把这个对象指向者个空间 * 123 * 132 A * B //此时lazyMan还没有完成构造 解决方法:去加volatile * */ // //反射 public static void main(String[] args) throws Exception { //(0) // LazyMan instance1 = LazyMan.getInstance2(); //把instance注释,让两个instance都让反射创建 (0)(3) Field passwords = LazyMan.class.getDeclaredField("PASSWORD"); //去拿值,改掉(5) passwords.setAccessible(true); //私有权限破坏掉 (5) Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);//获得空参构造器(0) declaredConstructor.setAccessible(true); //无视私有构造器 (0)(1) LazyMan instance1 = declaredConstructor.newInstance(); //反射创建对象instance2 (1) passwords.set(instance1,false); //(5)结论:道高一尺魔高一丈! LazyMan instance2 = declaredConstructor.newInstance(); // 都让反射创建(0)(3) System.out.println(instance1);//(0) System.out.println(instance2);//(0) } //(0) // //多线程并发 这里没有加volatile就会有问题 // public static void main(String[] args) { // for (int i = 0; i < 10; i++) { // new Thread(()->{ // LazyMan.getInstance2(); // }).start(); // } // } }