是一种编码套路
一个类只能创建一个实例
直接创建唯一实例
package com.by.entity;
?
/**
* 单例模式-饿汉式
*/
public class ClassA {
? ?//static: 1. newClassA可以访问返回 2. 静态属性内存中只会存在一个
? ?//private: 防止外界直接访问属性
? ?private static ClassA ca = new ClassA();
?
? ?//外界获取唯一实例的渠道
? ?//static:使外界直接通过类名访问
? ?public static ClassA newClassA(){
? ? ? ?return ca;
? }
?
? ?//构造私有化-防止外界调用构造创建对象
? ?private ClassA(){
?
? }
}
缺点: 有可能浪费空间
在获取实例是创建唯一对象
package com.by.entity;
?
/**
* 单例模式-懒汉式
*/
public class ClassB {
? ?//static: 1. newClassA可以访问返回 2. 静态属性内存中只会存在一个
? ?//private: 防止外界直接访问属性
? ?private static ClassB cb = null;
?
? ?//外界获取唯一实例的渠道
? ?//static:使外界直接通过类名访问
? ?//synchronized: 同步方法 预防线程安全问题
? ?public static synchronized ClassB newClassB(){
? ? ? ?
? ? ? ?if (cb == null) {//当第一次获取时再进行实例化
? ? ? ? ? ?cb = new ClassB();
? ? ? }
? ? ? ?return cb;
? }
?
? ?//构造私有化-防止外界调用构造创建对象
? ?private ClassB(){
?
? }
?
}
缺点: 线程效率慢
在懒汉式的基础上,利用同步代码块结合二次校验提高执行效率
package com.by.entity;
?
/**
* 单例模式-懒汉式进阶版
*/
public class ClassC {
? ?//static: 1. newClassA可以访问返回 2. 静态属性内存中只会存在一个
? ?//private: 防止外界直接访问属性
? ?private static ClassC cc = null;
?
? ?//外界获取唯一实例的渠道
? ?//static:使外界直接通过类名访问
? ?public static ClassC newClassC(){
? ? ? ?if (cc == null) {//二次校验: 决定是否需要开启互斥锁 t1:true t2:true
? ? ? ? ? ?synchronized (ClassC.class) {//临界资源对象: 当前类的类对象
? ? ? ? ? ? ? ?//对属性进行实例化
? ? ? ? ? ? ? ?if (cc == null) {//当第一次获取时再进行实例化
? ? ? ? ? ? ? ? ? ?cc = new ClassC();
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? }
? ? ? ?return cc;
? }
?
? ?//构造私有化-防止外界调用构造创建对象
? ?private ClassC(){
?
? }
?
}package com.by.entity;
?
/**
* 单例模式-懒汉式进阶版
*/
public class ClassC {
? ?//static: 1. newClassA可以访问返回 2. 静态属性内存中只会存在一个
? ?//private: 防止外界直接访问属性
? ?private static ClassC cc = null;
?
? ?//外界获取唯一实例的渠道
? ?//static:使外界直接通过类名访问
? ?public static ClassC newClassC(){
? ? ? ?if (cc == null) {//二次校验: 决定是否需要开启互斥锁 t1:true t2:true
? ? ? ? ? ?synchronized (ClassC.class) {//临界资源对象: 当前类的类对象
? ? ? ? ? ? ? ?//对属性进行实例化
? ? ? ? ? ? ? ?if (cc == null) {//当第一次获取时再进行实例化
? ? ? ? ? ? ? ? ? ?cc = new ClassC();
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? }
? ? ? ?return cc;
? }
?
? ?//构造私有化-防止外界调用构造创建对象
? ?private ClassC(){
?
? }
?
}
是一种底层技术,通常用于底层框架的编写
思路: 将数据的创建和维护交由工厂完成
需求: 构建一个工厂类,获取学生对象
提供学生类
package com.by.entity;
?
public class Student {
? ?private String name;
? ?private int age;
? ?private double score;
?
? ?public String getName() {
? ? ? ?return name;
? }
?
? ?public void setName(String name) {
? ? ? ?this.name = name;
? }
?
? ?public int getAge() {
? ? ? ?return age;
? }
?
? ?public void setAge(int age) {
? ? ? ?this.age = age;
? }
?
? ?public double getScore() {
? ? ? ?return score;
? }
?
? ?public void setScore(double score) {
? ? ? ?this.score = score;
? }
?
? ?@Override
? ?public String toString() {
? ? ? ?return "Student{" +
? ? ? ? ? ? ? ?"name='" + name + '\'' +
? ? ? ? ? ? ? ?", age=" + age +
? ? ? ? ? ? ? ?", score=" + score +
? ? ? ? ? ? ? ?'}';
? }
?
? ?public Student() {
? }
?
? ?public Student(String name, int age, double score) {//string,int,double
? ? ? ?this.name = name;
? ? ? ?this.age = age;
? ? ? ?this.score = score;
? }
}
书写配置文件
在项目下创建后缀名为.properties
的配置文件
作用: 存放被管理类的全限定名
以键=值
的形式存放数据
键值不可添加双引号、末尾不可添加分号、中间不可存在多个符号(如空格)
一行只能有一个键值对
StudentClassName=com.by.entity.Student
书写工厂类
package com.by.util;
?
import com.by.entity.Student;
?
import java.io.FileInputStream;
import java.util.Properties;
?
public class MyFactory {
? ?/**
? ? * 获取学生对象
? ? */
? ?public static Student getStudent(){
? ? ? ?Student student = null;
? ? ? ?try (
? ? ? ? ? ? ? ?//创建输入流
? ? ? ? ? ? ? ?FileInputStream fis=new FileInputStream("factory.properties")
? ? ? ? ? ? ? ) {
? ? ? ? ? ?//将配置文件的内容加载到集合中
? ? ? ? ? ?Properties p = new Properties();
? ? ? ? ? ?p.load(fis);
? ? ? ? ? ?//获取全限定名
? ? ? ? ? ?String className = p.getProperty("StudentClassName");
? ? ? ? ? ?//获取类对象
? ? ? ? ? ?Class c = Class.forName(className);
? ? ? ? ? ?//利用反射构建学生实例
? ? ? ? ? ?student = (Student) c.newInstance();
? ? ? } catch (Exception e) {
? ? ? ? ? ?System.out.println("未知异常!");
? ? ? ? ? ?e.printStackTrace();
? ? ? }
? ? ? ?return student;
?
? }
}
?
测试
package com.by.test;
?
import com.by.entity.Student;
import com.by.util.MyFactory;
?
public class Test5 {
? ?public static void main(String[] args) {
? ? ? ?//利用工厂获取学生实例对象
? ? ? ?Student s1 = MyFactory.getStudent();
? ? ? ?Student s2 = MyFactory.getStudent();
?
? }
}
?