单例模式,基于Java反射机制的实现

来源:互联网 发布:手机淘宝 怎么买运费险 编辑:程序博客网 时间:2024/05/21 10:31

在实际开发中,单例模式是一种很有用的设计模式,能很好的解决我们只需要类的一个实例的情况,单例模式常见的两种实现方式如下

懒汉式:

class Test {private static Test _instance;private Test() {}/** *  * @return 返回Test唯一实例 */public synchronized static Test getInstance() {if (null == _instance) {_instance = new Test();}return _instance;}}

饿汉式:

class Test {private static Test _instance = new Test();private Test() {}/** *  * @return 返回Test唯一实例 */public static Test getInstance() {return _instance;}}

按照上面这种写法,几乎所有单例都需要这段基本一样的代码,本文将介绍另外一种实现,可实现代码的复用,实现技巧:将单例看成是一种性质,而JDK1.5+的注解这一特性能很好的帮助我们解决这一需求,将类标记为单例。

1. 首先定义单例注解,注解的作用就是将类标记为单例

import java.lang.annotation.Documented;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 单例注解,该注解只能作用在类上,不能作用在方法上 */@Target({ java.lang.annotation.ElementType.ANNOTATION_TYPE, java.lang.annotation.ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Singleton {}

2. 定义对象工厂,用于解释我们的注解,并提供获取单例对象的方法

import java.lang.reflect.Constructor;import java.util.HashMap;import java.util.Map;/** *  * 对象工厂,用于解释我们的单例注解,并提供获取单例对象的方法 *  * @author xxx * @version 2014-4-14 */public final class New {/** * container to save Singleton */private static volatile Map<String, Object> objs = new HashMap<String, Object>();/** * 返回单例的静态方法,如果类没有用Singleton注解标记,则返回一个全新的实例 * 关于该方法线程安全 * @param clazz  * @return the Singleton */public static <T> T getInstance(Class<T> clazz) {String className = clazz.getName();synchronized (clazz) {/** * whether used the Single Annotation */if (clazz.isAnnotationPresent(Singleton.class)) {Object object = objs.get(className);if (object == null) {objs.put(className, newInstance(clazz));}return clazz.cast(objs.get(className));}return newInstance(clazz);}}private static <T> T newInstance(Class<T> clazz) {try {Constructor<T> constructor = clazz.getDeclaredConstructor();if (!constructor.isAccessible()) {constructor.setAccessible(true);}return constructor.newInstance();} catch (Exception e) {throw new NewInstanceException(e);}}}class NewInstanceException extends RuntimeException {/** *  */private static final long serialVersionUID = 1L;public NewInstanceException() {super();}public NewInstanceException(String message, Throwable cause) {super(message, cause);}public NewInstanceException(String message) {super(message);}public NewInstanceException(Throwable cause) {super(cause);}}


注:单例类,不能包含带参数构造方法,而对于无参构造函数是否公有物要求

至此,我的基于反射机制的单例模式核心代码,已经实现完毕。


测试代码:

public class Main {public static void main(String[] args) {Test instance1 = New.getInstance(Test.class);Test instance2 = New.getInstance(Test.class);System.out.println(instance1.hashCode() == instance2.hashCode());}}@Singletonclass Test {private Test() {}}

0 0
原创粉丝点击