目录
也就是说在整个软件运行过程中,从开始运行到最后的结束运行的过程中,要保证某一个类,只有一个实例,不可以再有第二个。
那么这样有什么用??
在网站开发等,有一个核心类,它非常耗用资源,但实际上我们只需要一个,那么这时候单例设计模式就很有价值
按照我们传统的写法,我们来写一个GirlFriend类
- public class SingleTon01 {
-
- public static void main(String[] args) {
- GirlFriend xh = new GirlFriend("小红");
- GirlFriend xb = new GirlFriend("小白");
- }
-
- }
-
- //有一个类,GirlFriend
- //只能有一个女朋友
- class GirlFriend{
-
- private String name;
-
- public GirlFriend(String name) {
- this.name = name;
- }
- }
举个例子,这个可以new出两个女朋友出来,那这就不叫单例,那么要如何保证单例呢?
我们可以这样写,首先将构造器私有化,我们会发现现在创建不了对象
但是我们会发现一个问题,我们一个女朋友都没有,这时候我们就要在类的内部创建
这时候这个对象在内部是创建出来了,可是它是私有的,我们在外部用不了,那么为了我们使用,我们就要提供一个公共的静态方法,返回gf对象
- public class SingleTon01 {
-
- public static void main(String[] args) {
- //通过方法获取对象
- GirlFriend instance = GirlFriend.getInstance();
- System.out.println(instance);
- }
-
- }
-
- //有一个类,GirlFriend
- //只能有一个女朋友
- class GirlFriend{
-
- private String name;
-
- //为了能够在静态方法中,返回gf对象,需要将其修饰为static
- private static GirlFriend gf = new GirlFriend("小红红");
- //如何保障我们只能创建一个 GirlFriend
- //步骤
- //1. 将构造器私有化
- //2. 在类的内部直接创建
- //3. 提供一个公共的static方法,返回gf对象
- private GirlFriend(String name) {
- this.name = name;
- }
-
- public static GirlFriend getInstance(){
- return gf;
- }
-
- @Override
- public String toString() {
- return "GirlFriend{" +
- "name='" + name + '\'' +
- '}';
- }
- }
那么有的人会想,我为什么要用static修饰这个getInstance呢?
如果我们不用static修饰这个方法,那么我们去用这个方法的时候又要去new对象,可是构造器已经被我们设置成private了,此时我们是new不了的,这时候直接通过类.方法名就可以直接调用。
此时我们可以尝试一下,再创建一个这个对象
- public static void main(String[] args) {
- //通过方法获取对象
- GirlFriend instance = GirlFriend.getInstance();
- System.out.println(instance);
-
- GirlFriend instance2 = GirlFriend.getInstance();
- System.out.println(instance);
-
- System.out.println(instance == instance2);
- }
由于是静态的,在类加载的时候就已经创建对象了,并且只会有一次,不会再创建新的
那么这为什么叫饿汉式?
在private static GirlFriend gf = new GirlFriend("小红红");中
这一步就已经创建了,也就是说只要类加载了,那么这个对象就已经创建了,即使我们没有去使用这个gf,它也会去创建
这时候我们在这个类里面添加一个静态变量,我们用类.属性名去调用,虽然我们没有调用那个静态方法,但是这个对象还是被创建出来了,也就是说饿汉式造成了创建对象,但是没有使用,这样就造成了资源浪费
- public class SingleTon01 {
- public static void main(String[] args) {
- System.out.println(GirlFriend.age);
- }
-
- }
- //有一个类,GirlFriend
- //只能有一个女朋友
- class GirlFriend{
-
- private String name;
- public static int age = 18;
- //为了能够在静态方法中,返回gf对象,需要将其修饰为static
- private static GirlFriend gf = new GirlFriend("小红红");
- //如何保障我们只能创建一个 GirlFriend
- //步骤
- //1. 将构造器私有化
- //2. 在类的内部直接创建
- //3. 提供一个公共的static方法,返回gf对象
- private GirlFriend(String name) {
- System.out.println("构造器被调用...");
- this.name = name;
- }
-
- public static GirlFriend getInstance(){
- return gf;
- }
- @Override
- public String toString() {
- return "GirlFriend{" +
- "name='" + name + '\'' +
- '}';
- }
- }
- public class SingleTon02 {
- public static void main(String[] args) {
- System.out.println(Cat.n1);
- Cat instance = Cat.getInstance();
- System.out.println(instance);
- }
-
- }
- //希望在程序运行过程中,只能创建一个Cat对象
- //使用单例模式
- class Cat{
-
- private String name;
- private static Cat cat;
- public static int n1 = 999;
-
- //步骤
- //1.仍然将构造器私有化
- //2.定义一个静态属性
- //3.提供一个public的static方法,可以返回一个Cat对象
- private Cat(String name) {
- System.out.println("构造器调用....");
- this.name = name;
- }
-
- public static Cat getInstance(){
- if (cat == null){ //如果还没创建cat对象
- cat = new Cat("小可爱");
- }
- return cat;
- }
- @Override
- public String toString() {
- return "Cat{" +
- "name='" + name + '\'' +
- '}';
- }
- }
这时候我们去调用这个Cat类里的n1属性,Cat对象没有随着类加载而创建出来,当我们想去创建这个对象的时候,可以通过getInstance方法来创建对象,并且将创建完的对象返回