本文版权归作者所有,仅供用来网上学习来用,读者可以收藏,请不要下载到本机和重新发布到其它网站
有觉得可以改进的,请留言,也可加群讨论71326533
我们在实际开发中,会大量采用单例模式。但是我们常常疲于写那几个单调的方法,还可考虑同步的问题,下面就是一个常用的单例模式的写法:
public class Singleton {
private Singleton() {
}
... ...
... ...
}
为了减少重复的写这些无聊的代码,我写了一个类,用来统一管理这些单例对象
import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SingletonFactory {
public static final Logger LOG = Logger.getLogger(SingletonFactory.class.getCanonicalName());
private static final Map<Class<?>, Object> INSTANCE_MAP = Collections.synchronizedMap(new HashMap<Class<?>, Object>());
private static final Object[] EMPTY_ARGS = new Object[0];
/**
* <pre>
* 用此方法有一个前提:
* 参数类必须有显示声明的无参构造器或没有任何显示声明的构造器
* </pre>
*/
public static <T> T getInstance(Class<? extends T> clazz) {
return getInstance(clazz, EMPTY_ARGS);
}
/**
* <pre>
* 用此方法有两个前提:
* 1. 参数数组的项都不能为null
* 2. 参数数组的项都不能是简单数据类型
* </pre>
*/
public static <T> T getInstance(Class<? extends T> clazz, Object... args) {
Object object = INSTANCE_MAP.get(clazz);
if (object == null) {
Class<?>[] parameterTypes = new Class<?>[args.length];
for (int i = 0; i < args.length; i++) {
parameterTypes[i] = args[i].getClass();
}
return getInstance(clazz, parameterTypes, args);
}
return clazz.cast(object);
}
/**
* <pre>
* 用此方法有三个前提:
* 1. 两个参数数组同时为null或同时不为null
* 2. 两个数组的长度必须相等
* 3. parameterTypes如果不空null, 则其各元素不能为null
* </pre>
*/
public static <T> T getInstance(Class<? extends T> clazz, Class<?>[] parameterTypes, Object[] args) {
Object object = INSTANCE_MAP.get(clazz);
if (object == null) { // 检查实例,如是不存在就进行同步代码区
synchronized (clazz) { // 对其进行锁,防止两个线程同时进入同步代码区
// 双重检查,非常重要,如果两个同时访问的线程,当第一线程访问完同步代码区后,生成一个实例;当第二个已进入getInstance方法等待的线程进入同步代码区时,也会产生一个新的实例
if (object == null) {
try {
if (parameterTypes != null && args != null) {
if (parameterTypes.length == args.length) {
Constructor<?> constructor = clazz.getDeclaredConstructor(parameterTypes);
constructor.setAccessible(true);
T instance = clazz.cast(constructor.newInstance(args));
INSTANCE_MAP.put(clazz, instance);
return instance;
} else {
throw new IllegalArgumentException("参数个数不匹配");
}
} else if (parameterTypes == null && args == null) {
T instance = clazz.newInstance();
INSTANCE_MAP.put(clazz, instance);
return instance;
} else {
throw new IllegalArgumentException("两个参数数组必须同时为null或同时不为null");
}
} catch (Exception e) {
LOG.log(Level.SEVERE, "创建实例失败", e);
}
}
}
}
return null;
}
}
用法很简单
public class SingletonTest {
public static void main(String[] args) {
Singleton obj1 = SingletonFactory.getInstance(Singleton.class);
Singleton obj2 = SingletonFactory.getInstance(Singleton.class);
System.out.println(obj1 == obj2);
}
}
结果:
true
这里统一管理这些单例对象,且单例对象的构造器可以为私有的。如果需要带参数,则需要使用public static <T> T getInstance(Class<? extends T> clazz, Class<?>[] parameterTypes, Object[] args)方法
分享到:
相关推荐
主要介绍了Java单例模式下的MongoDB数据库操作工具类,结合实例形式分析了java基于单例模式下操作MongoDB数据库相关连接、查询、插入、删除等操作封装技巧,需要的朋友可以参考下
Java一共有23种设计模式,单例模式就是指一个类只有一个实例,且该类能自行创建这个实例的一种模式。可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。比如咱们电脑...
数据库工具类,采用的DBCP的连接池。并且采用了Google公司的工程师Bob Lee写的新的懒汉单例模式来构造连接工厂。并将获取到的数据库连接绑定到当前线程中。这样可以有效的防止申请连接的滥用。
目录: 前 言 第一部分 大旗不挥,谁敢冲锋——热身篇 第1章 单一职责原则 1.1 我是“牛”类,我可以担任多职吗 1.2 绝杀技,打破你的传统思维 ...38.1.5 工具类 38.2 最佳实践 附录:23个设计模式
本专栏主要为Java程序设计(基础)实验报告和Java程序设计(进阶)...进阶篇有反射、泛型、注解、网络编程、多线程、序列化、数据库、Servlet、JSP、XML解析、单例模式与枚举。本专栏主要为Java入门者提供实验参考。
JAVA例单模式源码DCP 设置工具 用于生成复杂、稳定和跨平台的 Java 安装程序的 Java 程序。 观看在 2 分钟内制作的 DCP Setup Maker 安装程序的演示: “其直观的用户界面和卓越的易用性使得构建包含大量文件的复杂...
本系统基于六种设计模式,运用到的设计模式有备忘录模式,简单工厂模式,迭代器模式,状态模式,模版方法模式,单例模式。 具体实现过程、UML类图以及实现效果详见如下项目说明地址: ... 该系统为绘图系统,该系统通过...
接口绑定到实现类,无论是在单例还是实例范围内。 主要目标是使用 构建的 Web 服务器和客户端应用程序,不过也在名为 . 使用这个核心工具,每个其他模块都被构建为一个独立的服务,旨在通过可以轻松覆盖的接口公开...
在Java,一般常用在工具类的实现或创建对象需要消耗资源。 常见应用场景: 1、任务管理器 2、回收站 3、网站计数器 4、数据库连接池 优点: 1、单例模式只能产生一个实例,减少了系统性能的开销,当一个对象的产生...
这是一款很好用的API工具,是每个程序员所必备的工具
4.注释非常全,除了跟模式无关的辅助工具类的每一个类,每一个方法,每一个属性都有注释; 5.每一种模式都分配一个readme文件做为说明; 6.除了最简单的单例模式,每一种模式都有>=2套示例代码; 7.这都是在网上找了...
JAVA例单模式源码高桥 GoAopBridge 通过 Go 添加了对面向方面编程的支持! Laravel5 应用程序的 AOP 框架。 概述 面向方面的范式允许使用特殊工具扩展标准的面向对象范式,以有效解决应用程序中的横切关注点。 此...
DeviceStatusUtils 手机状态工具类 主要包括网络、蓝牙、屏幕亮度、飞行模式、音量等 DigestUtils DigestUtils FileUtils 文件操作 HanziToPinyin 拼音汉字处理 IOUtils IOUtils MD5 MD5 MiscUtils 设备信息的获取 ...
NULL 博文链接:https://java--hhf.iteye.com/blog/2171034
什么是Java中的单例模式?如何实现线程安全的单例模式? 什么是Java中的生命周期回调方法?列举一些常见的生命周期回调方法。 什么是Java中的注解处理器?如何自定义和使用注解处理器? 什么是Java中的并发编程?...
本专栏主要为Java程序设计(基础)实验报告和Java程序设计(进阶)...进阶篇有反射、泛型、注解、网络编程、多线程、序列化、数据库、Servlet、JSP、XML解析、单例模式与枚举。本专栏主要为Java入门者提供实验参考。
以前写了一个java的正规表达式的java工具类,分享一下,有用到的欢迎下载使用。 如果你有常用的定义好的,且测试通过的正规表达式,欢迎跟贴,也让我享用一下 . 类中用到了 jakarta-oro-2.0.jar 包,请大家自己在 ...
Collections--集合工具类 83 Arrays—数组对象工具类 84 增强for循环 85 可变参数(...) 86 枚举:关键字 enum 86 自动拆装箱 86 泛型 87 <java.lang>System 89 <java.lang>Runtime 90 <java.lang>Math 90 <java....
单例模式 行为模式 责任链模式 命令模式 解释器模式 迭代器模式 中介者模式 备忘录模式 观察者模式 状态模式 策略模式 模板方法模式 访问者模式 设计案例 UML 架构 系统架构能力 基本理论 扩展性...