单例模式:
单例模式是指在程序运行过程中,某个类在内存中只有一个对象,即让一个类只能创建一个对象,所以单例模式不能用new关键字创建
单例模式一般分为两种情况,饿汉式和懒汉式
创建单例模式的步骤:
1构造方法私有化private,保证外部访问不到构造方法,否则可以创建无限多个对象,私有化构造方法后系统不再提供默认的构造方法
2创建私有的private静态的static 当前对象类对象(饿汉式)/可见的volitale当前类对象的引用(懒汉式或延时加载)
3对外提供公共的public静态的static访问方法,将单例对象暴漏给外部,让外部能访问到单例类的对象
注意:2中成员变量要是私有的静态的,如果不是静态的,3中的静态方法访问不到这个成员变量.
3中的公共方法必须要是静态的,才可以通过类名.方法名的方式调用该方法
为了防止多线程调用懒汉式创建多个对象,懒汉式的访问方法要设置成同步的synchronized
创建示例:
package chen_chapter_9;
public class SingleTest01 {
public static void main(String[] args) {
Single s1 = Single.getInstance();
Single s2 = Single.getInstance();
System.out.println(s1 == s2);
Slone s3 = Slone.getInstance();
Slone s4 = Slone.getInstance();
System.out.println(s3 == s4);
}
}
//懒汉式
class Single {
// 1私有化构造方法
private Single() {
}
// 2创建当前单例类对象,因为是饿汉,所以先创建对象,为了不被外部访问,要私有化,且静态
private static Single s = new Single();
// 3提供给外部能访问的方法,返回该单例模式的对象,因为只能通过类名.方法的方式访问该方法,所以该方法要是静态的
public static Single getInstance() {
return s;
}
}
//饿汉式
class Slone {
// 1私有化构造方法
private Slone() {
}
// 2创建单例类的引用,不能直接被外面访问,用private,对多线程可见,要用volitale关键字
private static volatile Slone slone = null;
// 3提供公共方法,以返回该单例对象
public static synchronized Slone getInstance() {
if (slone == null) {
slone = new Slone();
}
return slone;
}
}
out:
true
true两个对象的内存地址相同,说明是同一个对象
java示例:
java源码提供了一个Runtime类,这个类是一个单例模式,查看部分源码:
public class Runtime {
private static final Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
/** Don't let anyone else instantiate this class */不能被任何人实例化
private Runtime() {}
//该函数可以执行windows的一些命令如画图mspaint,关机shutdown, logoff注销命令,
//notepad——–打开记事本,dvdplay——–DVD播放器等
public Process exec(String command) throws IOException {
return exec(command, null, null);
}
使用exec示例:
import java.io.IOException;
public class RuntimeTest01 {
public static void main(String[] args) {
Runtime rt = Runtime.getRuntime();
try {
rt.exec(" explorer");//打开文件浏览器
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我们之前用到的Calendar日历类,是抽象类,不能通过new来创建对象,它有getInstance方法,可以使用该方法获得此类型的一个通用对象,但是Calendar类并不是单例模式,所以不是所有私有构造方法、对外通过getInstance方法提供实例的类都是单例模式,Calendar是抽象类
public static Calendar getInstance()
{
Locale aLocale = Locale.getDefault(Locale.Category.FORMAT);
return createCalendar(defaultTimeZone(aLocale), aLocale);
}
//默认返回当前国家/地区下的日期格式
简单使用Calendar获取当前年月日:
import java.util.Calendar;
public class CalendarTest01 {
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.YEAR));
System.out.println(c.get(Calendar.MONTH) + 1);// 0表示1月份
System.out.println(c.get(Calendar.DAY_OF_MONTH));
}
}
out:
2018
11
25