定义:只能生成一个实例。并且它自己负责创建自己的对象,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。例如:回收站。
实现方式:
1.饿汉模式(快加载) 类初始化顺序:静态变量 静态块 实例变量 实例块 构造函数
class People{
private static People people = new People();//方法区 直接new对象
private People(){}//私有的构造函数
public static People getInstance()//向外提供的共有的获取对象的接口
{
return people;
}
}
特点:线程安全,直接在静态变量new对象,也就是在编译期就已经给对象分配内存。提供一个公有的静态接口。
2.懒汉模式(慢加载)
class People{
private static People people;
private People(){}
public static People getInstance()
{
if(people == null)
{
people = new People();
}
return people;
}
}
特点:线程不是安全的。静态变量一开始不会赋初值。提供一个共有的静态方法,判断对象是否为null,为null就new一个对象。是在调用该方法的运行期实现的。
区别:new对象的时机不同。一个在类加载过程,一个在类加载完后调用静态方法生成对象。
3.静态内部类
特点:线程安全的。在编译期就对静态块的类就分配内存了。
class People{
static class PeopleInnerClass{
static People people = new People();
}
private People(){}
public static People getInstance()
{
return PeopleInnerClass.people;
}
}
4.枚举实现
class EnumSington{
private enum Inner
{//类加载时候是安全的
INSTANCE;//枚举实例 一个枚举实例构造函数只会加载一次就会实现单例
private EnumSington sington;//唯一的实例
Inner()
{
sington = new EnumSington();
}
private EnumSington getSington()
{
return sington;
}
}
public static EnumSington getInstance()//普通方法需要用实例对象调用
{
return Inner.INSTANCE.getSington();
}
}
特点 : 简单 安全。
为什么枚举实现的单例更加安全:
1)枚举自己处理序列化;(禁用了writeObject()和readObject()方法,永远返回是同一个实例)
2)枚举实例的创建是线程安全的。
序列化:对象永久的存储在磁盘上。将把Java对象转换为字节序列的过程。
反序列化:恢复磁盘上的对象。指把字节序列恢复为Java对象的过程。