将泛型用于单例模式

来源:互联网 发布:淘宝店铺监控 编辑:程序博客网 时间:2024/05/05 09:21

本是一次java作业,要求将泛型用到单例模式中去。本来以为很简单,只要把前面写过的单例模式加个泛型就行了,然而当我开始下手后,却发现并不是那么简单。

  1. 最开始的思路是这样的,使用最简单的单例模式“懒汉模式”:
    懒汉模式
    参考于实验楼。
    后面发现泛型无法应用于静态变量,所以只能换一种思路。

  2. 然后就想到了使用容器来实现单利单例模式,因为容易能很好的和泛型兼容。
    所以就写出了如下代码:

import java.util.concurrent.*;class Apple {    private int color;    public Apple() {        color = 20;    }    public int getColor() {        return color;    }    public void setColor(int color) {        this.color = color;    }}public class SingletonMode<T> {    private static final ConcurrentMap<Class, Object> map = new ConcurrentHashMap<>();    public static<T> T getSingleton(Class<T> type) {        Object ob = map.get(cla);        if(ob == null) {            try {                ob = type.newInstance();                map.put(type, ob);            } catch (InstantiationException e) {                e.printStackTrace();            } catch (IllegalAccessException e) {                e.printStackTrace();            }        }        return (T)ob;    }    public static void main(String[] args) {        Apple apple1 = getSingleton(Apple.class);        Apple apple2 = getSingleton(Apple.class);        System.out.println(apple1.getColor());        System.out.println(apple2.getColor());        apple1.setColor(10);        System.out.println(apple2.getColor());    }}

但是这样还是有问题的,因为Class.newInstance() 要求被调用的构造函数是可见的,也即必须是public类型的,所以这种单例模式是不完全的,还是能够通过直接调用类中的构造器生成对个对象。于是我又上网查了一波资料,想找到能够访问私有构造器的方法,结果还真叫我找到了,那就是使用反射。
3. 也就是要先获取到这个类的构造器,然后把Accessible设为true,就可以访问了,代码如下:

import java.util.concurrent.*;import java.lang.reflect.Constructor;class Apple {    private int color;    private Apple() {        color = 20;    }    public int getColor() {        return color;    }    public void setColor(int color) {        this.color = color;    }}public class SingletonMode<T> {    private static final ConcurrentMap<Class, Object> map = new ConcurrentHashMap<>();    public static<T> T getSingleton(Class<T> type, String className) {        Object ob = map.get(type);        if(ob == null) {            try {                Class c = Class.forName(className);                Constructor c0 = c.getDeclaredConstructor();                c0.setAccessible(true);                ob = (T)c0.newInstance();                map.put(type, ob);            } catch (Exception e) {                e.printStackTrace();            }        }        return (T)ob;    }    public static void main(String[] args) {        Apple apple1 = getSingleton(Apple.class, "Apple");        Apple apple2 = getSingleton(Apple.class, "Apple");        System.out.println(apple1.getColor());        System.out.println(apple2.getColor());        apple1.setColor(10);        System.out.println(apple2.getColor());    }}

参考博客:http://xiaohuafyle.iteye.com/blog/1607258
https://my.oschina.net/heavenly/blog/502574

0 0
原创粉丝点击