第一先解释一下创建型:
创建型:使得对象的创建与使用分离
单利模式==》直白点 构造器私有化 (外部不能创建该类的对象)只有加载类或者调用一定的方法才可创建对象,但是这并不是一定(毕竟还有反射这个bug,它可以获取类的私有构造方法)
1、饿汉式:直白点:就是说在类的加载时,不会管你用不用,都会给你想创建(这也是他的缺点,如果你一直不用 那不就造成浪费了么)贴一个饿汉的demo
package com.ljb.hungerMan;
/**
* Copyright (C), 2022-2030, Chongqing Mac info. Co., Ltd.
* 设计模式中创建型模式中的单例模式 中的饿汉式单例模式
* @author Sw_Ljb
* @version 1.0
* @ClassName hungerManTest
* @Date 2022/4/20上午11:33
*/
public class hungerManTest {
//饿汉 先将构造其私有化 不让外界访问
private hungerManTest(){
super();
}
private final static hungerManTest hun = new hungerManTest();
public final static hungerManTest hungerManMethod(){
return hun;
}
}
2、懒汉式:(构造器 私有化 只用当调用方法时创建 (你看 调用方法,如果是一个线程调用该方法 那还好,但是如果是多线程了 他们都来调用该方法,这不就有线程安全了)(OK 你说你加锁 加锁后记得加上一个volatile 众所周知new一个对象是要经过三步骤的 1、分配内存空间2、执行构造方法 初始化对象 3、把这个对象指向这个空间 执行这三步也可能出错 ==》产生指令重排现象 加上volatile就可以预防指令重排 如果没有反射没准你就成了 奈何有反射 反射创建 你就废了))(最后 你不开心 你说OK你加一个没人知道的私有的红绿灯(一个变量)(boolean类型) 当创建一个后 就改变它的值 不让这的个方法再调用 你最好不要让我知道它的名字 不然反射这个变量 然后变量.set方法 就可以改变它值 你就又废了)害 说这么多 贴个代码
package com.ljb.layMan;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
* Copyright (C), 2022-2030, Chongqing Mac info. Co., Ltd.
* 懒汉式
* @author Sw_Ljb
* @version 1.0
* @ClassName layMan
* @Date 2022/4/20下午2:33
*/
public class layMan {
//红率灯
private static boolean mima = false;
/* 不加 红绿灯 使用反射 还是会破解
private layMan() {
synchronized (com.ljb.layMan.layMan.class) {
if (layMan != null){
throw new RuntimeException("不要试图使用反射 破坏");
}
}
}
*/
private layMan() {
synchronized (com.ljb.layMan.layMan.class) {
if (mima == false){
mima =true;
} else{
throw new RuntimeException("不要试图使用反射 破坏");
}
}
}
//保证不能指令重排
private volatile static layMan layMan;
public static layMan getinstence(){
if (layMan==null){
synchronized (layMan.class) {
if (layMan == null) {
layMan = new layMan();
/*
new一个对象的三个步骤
1、分配内存空间
2、执行构造方法 初始化对象
3、把这个对象指向这个空间
在new 执行这三步骤的时候 如果不对变量进行volatile限制
会发生指令重排
*/
}
}
}
return layMan;
}
/*
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(()->{
layMan.getinstence();
}).start();
}
}
*/
public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, NoSuchFieldException {
// com.ljb.layMan.layMan layMan1 = layMan.getinstence();
Constructor<com.ljb.layMan.layMan> declaredConstructor = com.ljb.layMan.layMan.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
Field mima = com.ljb.layMan.layMan.class.getDeclaredField("mima");
com.ljb.layMan.layMan layMan = declaredConstructor.newInstance();
mima.set(layMan,false);
com.ljb.layMan.layMan layMan3 = declaredConstructor.newInstance();
System.out.println(layMan3);
System.out.println(layMan);
}
}
3、静态内部类
在内部类中中new一个外部类的对象 在外部类中提供一个私有方法去得到一个外部类的对象
贴个代码:
package com.ljb.innerClass;
import javax.xml.ws.Holder;
/**
* Copyright (C), 2022-2030, Chongqing Mac info. Co., Ltd.
*
* @author Sw_Ljb
* @version 1.0
* @ClassName innnerClassTest
* @Date 2022/4/20下午2:58
*/
public class OuterClass {
private OuterClass() {
}
private static OuterClass getInstance(){
return innerclass.outer;
}
public static class innerclass{
private static final OuterClass outer = new OuterClass();
}
}