java
中单例模式是一种常见的设计模式,
单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
单例模式有一下特点:
1、单例类只能有一个实例。
2、单例类必须自己自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
//单例实例变量
private static SingletonOne instance = null;
private SingletonOne(){
}
public static SingletonOne getInstance(){
if (instance == null) {
return instance;
}
private static SingletonTwo instance = new SingletonTwo();
private SingletonTwo(){
}
public static SingletonTwo getInstance(){
return instance;
}
private static Map map = new HashMap();
static{
SingletonFive single = new SingletonFive();
map.put(single.getClass().getName(), single);
}
protected SingletonFive() {
}
public static SingletonFive getInstance(String name){
if (name == null) {
if (map.get(name) == null) {
return map.get(name);
}
public String about(){
return "hello,i am regsinleton";
}
public static void main(String[] args) {
单例模式有一下特点:
1、单例类只能有一个实例。
2、单例类必须自己自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
懒汉式单例、
public class SingletonOne {
instance = new SingletonOne();
}
}
饿汉式单例、
public class SingletonTwo {
//单例变量,static的,在类加载时进行初始化一次,保证线程安全
}
登记式单例
public class SingletonFive {
name = SingletonFive.class.getName();
System.out.println("name=null"+"---->name="+name);
}
try {
map.put(name, (SingletonFive)Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
SingletonFive single = SingletonFive.getInstance(null);
System.out.println(single.about());
}
}
通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效
如何禁止外部通过反射来做单例对象的实例化
System.setSecurityManager(new SecurityManager(){
@Override
public void checkPermission(Permission perm) {
if (perm instanceof ReflectPermission && "suppressAccessChecks".equals(perm.getName())) {
for (StackTraceElement elem:Thread.currentThread().getStackTrace()) {
if (elem.getClassName().endsWith("Two")) {
throw new SecurityException();
}
}
}
}
});
SingletonTwo singleton = SingletonTwo.getInstance();
System.out.println(singleton);
Class<?> clazz = SingletonTwo.class;
SingletonTwo ref = (SingletonTwo) clazz.newInstance();
System.out.println(ref);