java中的单例模式
来源:互联网 发布:mac常用快捷键一览 编辑:程序博客网 时间:2024/06/10 02:48
java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
单例模式有一下特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。
饿汉式单例类
饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton1 {
//私有的默认构造子
private Singleton1() {}
//已经自行实例化
private static final Singleton1 single = new Singleton1();
//静态工厂方法
public static Singleton1 getInstance() {
return single;
}
}
懒汉式单例类
懒汉式单例类.在第一次调用的时候实例化
public class Singleton2 {
//私有的默认构造子
private Singleton2() {}
//注意,这里没有final
private static Singleton2 single=null;
//静态工厂方法
public synchronized static Singleton2 getInstance() {
if (single == null) {
single = new Singleton2();
}
return single;
}
}
3.登记式单例类
import java.util.HashMap;
import java.util.Map;
//登记式单例类.
//类似Spring里面的方法,将类名注册,下次从里面直接获取。
public class Singleton3 {
private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
static{
Singleton3 single = new Singleton3();
map.put(single.getClass().getName(), single);
}
//保护的默认构造子
protected Singleton3(){}
//静态工厂方法,返还此类惟一的实例
public static Singleton3 getInstance(String name) {
if(name == null) {
name = Singleton3.class.getName();
System.out.println("name == null"+"--->name="+name);
}
if(map.get(name) == null) {
try {
map.put(name, (Singleton3) Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}
//一个示意性的商业方法
public String about() {
return "Hello, I am RegSingleton.";
}
public static void main(String[] args) {
Singleton3 single3 = Singleton3.getInstance(null);
System.out.println(single3.about());
}
}
////////////////////////////////////////////////////////////////java中用反射来破坏单例
以饿汉式为例:
public static void main(String[] args) {
getInstance1();
}
public static void getInstance1()
{
try {
Class c = Class.forName("MySingleton"); //通过类名,得到Class
//Method[] m = c.getMethods();
//:此方法只能拿到public的属性:Field [] f = c.getFields();
MySingleton m1 = (MySingleton)c.newInstance();//只要名字为"MySingleton"的类存在,则此句话执行成功,因为可以调用构造方法,虽然它是私有的。
Field[] f = c.getDeclaredFields(); //可以拿到所有的属性
for(Field f1 : f)
{
System.out.println(f1.getName());
}
Field ff = c.getDeclaredField("single");
ff.setAccessible(true);//设置为此属性可以被改变值
ff.set(ff, new MySingleton());//如果不加final,则此句话不会报错,从而导致并不是一个单例。
//当然,用MySingleton m2 = (MySingleton)c.newInstance();本身就可以产生第二个对象了
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
单例模式有一下特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。
饿汉式单例类
饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton1 {
//私有的默认构造子
private Singleton1() {}
//已经自行实例化
private static final Singleton1 single = new Singleton1();
//静态工厂方法
public static Singleton1 getInstance() {
return single;
}
}
懒汉式单例类
懒汉式单例类.在第一次调用的时候实例化
public class Singleton2 {
//私有的默认构造子
private Singleton2() {}
//注意,这里没有final
private static Singleton2 single=null;
//静态工厂方法
public synchronized static Singleton2 getInstance() {
if (single == null) {
single = new Singleton2();
}
return single;
}
}
3.登记式单例类
import java.util.HashMap;
import java.util.Map;
//登记式单例类.
//类似Spring里面的方法,将类名注册,下次从里面直接获取。
public class Singleton3 {
private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
static{
Singleton3 single = new Singleton3();
map.put(single.getClass().getName(), single);
}
//保护的默认构造子
protected Singleton3(){}
//静态工厂方法,返还此类惟一的实例
public static Singleton3 getInstance(String name) {
if(name == null) {
name = Singleton3.class.getName();
System.out.println("name == null"+"--->name="+name);
}
if(map.get(name) == null) {
try {
map.put(name, (Singleton3) Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}
//一个示意性的商业方法
public String about() {
return "Hello, I am RegSingleton.";
}
public static void main(String[] args) {
Singleton3 single3 = Singleton3.getInstance(null);
System.out.println(single3.about());
}
}
////////////////////////////////////////////////////////////////java中用反射来破坏单例
以饿汉式为例:
public static void main(String[] args) {
getInstance1();
}
public static void getInstance1()
{
try {
Class c = Class.forName("MySingleton"); //通过类名,得到Class
//Method[] m = c.getMethods();
//:此方法只能拿到public的属性:Field [] f = c.getFields();
MySingleton m1 = (MySingleton)c.newInstance();//只要名字为"MySingleton"的类存在,则此句话执行成功,因为可以调用构造方法,虽然它是私有的。
Field[] f = c.getDeclaredFields(); //可以拿到所有的属性
for(Field f1 : f)
{
System.out.println(f1.getName());
}
Field ff = c.getDeclaredField("single");
ff.setAccessible(true);//设置为此属性可以被改变值
ff.set(ff, new MySingleton());//如果不加final,则此句话不会报错,从而导致并不是一个单例。
//当然,用MySingleton m2 = (MySingleton)c.newInstance();本身就可以产生第二个对象了
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
- java中的单例模式
- java中的单例模式
- java中的单例模式
- java中的单例模式
- Java中的单例模式
- java中的单例模式
- java中的单例模式
- Java中的单例模式
- JAVA中的单例模式
- Java中的单例模式
- java中的单例模式
- JAVA中的单例模式
- Java中的单例模式
- Java中的单例模式
- java中的单例模式
- java中的单例模式
- Java中的单例模式
- java中的单例模式
- Unix 传奇
- iOS Push-Notification Badge auto increment
- 使用嵌入式关系型SQLite数据库存储数据
- Visual C++ 2012 Express也可以写WinForm程序
- 通知栏提示 Status Bar Notifications
- java中的单例模式
- Android读取音乐视频图片文件
- java基础学习笔记(五) 文字的编码方案
- IPA
- 导入Excel遇到数字字母混合列,字母导入为空值发生数据丢失时,用以下方法解决!
- android in practice_Communicating with a Service (portfolio project)
- windows 命令方式查找指定IP的MAC地址
- jni调用汇总(java传各种类型的数据给c)
- thin