> 文章列表 > 单例设计模式,final,

单例设计模式,final,

单例设计模式,final,

  1. 设计模式就是在大量的实践中总结和理论化之后优选的代码结构,编程风格,以及解决问题的思考方法。设计模式就像经典的棋谱,不同的棋局,我们用不同的棋谱,免得我们自己在思考和摸索。
  2. 单例模式:类的单例模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法
  3. 单例模式(饿汉式,懒汉式)
  4. 饿汉式:有可能造成资源的浪费
    package com.hspedu.single_;import java.lang.reflect.GenericArrayType;public class SingleTon01 {public static void main(String[] args) {//通过方法可以获取对象GirlFriend instance = GirlFriend.getInstance();System.out.println(instance);GirlFriend instance1 = GirlFriend.getInstance();System.out.println(instance1);//这里并不会创建两个对象//因为在类加载的时候,static只加载一次,返回的都是gf对象/*GirlFriend{name='小白'}GirlFriend{name='小白'}*/}}
    //有一个类,GirlFriend
    class GirlFriend{private String name;//直接创建()//为了能够在静态方法中,返回gf对象,需要将其修饰为staticprivate static GirlFriend gf = new GirlFriend("小白");//如何保障我们只能创建一个GirlFriend对象(饿汉式:类加载的时候就创建好了,虽然你还没打算用)//1.将构造器私有化private(防止外部直接创建,这样之后一个对象也创建不了)//2.在类的内部直接创建对象(该对象static)//3.提供一个公共的static方法,返回gf对象private GirlFriend(String name) {this.name = name;}//为什么必须是静态的方法(因为非静态方法要创建对象调用,静态可以直接类名调用)public static GirlFriend getInstance(){return gf;}@Overridepublic String toString() {return "GirlFriend{" +"name='" + name + '\\'' +'}';}
    }
    

    gf对象类加载的时候就创建好了,虽然你还没打算用,比较着急

  5. 懒汉式:使用了才创建

    1. package com.hspedu.single_;/* 懒汉式单例模式*/
      public class SingleTon02 {public static void main(String[] args) {//这样才会创建对象,类加载的时候不会创建对象。Cat instance = Cat.getInstance();System.out.println(instance);}
      }
      //希望在程序运行过程中只能创建一个Cat对象
      class Cat{private String name;private static Cat cat;//没有创建默认为null//步骤//1.仍然构造器私有化//2.定义一个static静态属性对象//3.提供一个public的static方法,可以返回一个Cat对象//4.懒汉式,不浪费空间。private Cat(String name) {this.name = name;}public static Cat getInstance(){if(cat==null){//如果没有创建cat对象cat = new Cat("橘猫");}return cat;}@Overridepublic String toString() {return "Cat{" +"name='" + name + '\\'' +'}';}
      }
  6. 两者区别

    1. 创建时机不同,饿汉式在类加载,懒汉式在使用时才创建。

    2. 饿汉式不存在线程安全问题,懒汉式存在线程安全问题

    3. 饿汉式有可能浪费资源,懒汉式没有

  7. final关键字

    1. final可以修饰类,属性,方法和局部变量

    2. 当不希望类被继承时,可以用final修饰

    3. 不希望父类的某个方法被子类覆盖/重写时,可以用final关键字修饰

    4. 当不希望类的某个属性的值被修改,可以final修饰public final int n1=100;

    5. 不希望局部变量被修改用final

  8. final注意事项

    1. package com.hspedu.final_;public class FinalDetail01 {public static void main(String[] args) {CC cc = new CC();new EE().cal();//没有问题}
      }
      class AA{public final double TAX_RATE=0.04;//定义时:/*修饰属性是非静态1.定义时:2.在构造器3.在代码块中*/public final double TAX_RATE1;public final double TAX_RATE2;public AA() {//在构造器TAX_RATE1=1.1;}{//在代码块中TAX_RATE2 = 2.2;}
      }class BB{/*如果final修饰的属性是静态的,则初始化的位置只能是1.定义时2.在静态代码块,不能在构造器中赋值final静态属性在类加载的时候没有给值是不允许的,构造器在创建对象时才被引用。静态代码块在类加载时就被调用了*/public static final double TAX01 = 99.9;public static final double TAX02;
      //    public static final double TAX03;
      //    public BB(){
      //        TAX03 = 97.9;
      //    }不允许这种方法赋值static {TAX02=98.9;}}
      //final类不能继承,但可以实例化对象
      final class CC{}
      //如果类不是final类,但含有final方法,则该方法虽然不能重写,但可以被继承
      class DD{public final void cal(){System.out.println("cal方法");}
      }
      class EE extends DD{}

      final修饰的属性是常量,一般用XX_XX_XX来命名。

    2. package com.hspedu.final_;public class FinalDetail02 {public static void main(String[] args) {System.out.println(BBB.num);//包装类,String类是final类,不能被继承。}
      }
      //final和static往往搭配使用,效率更高,不会导致类加载,底层编译器做了优化处理
      class BBB{public final static int num =1000;static {System.out.println("BBB 静态代码块被执行");}
      }
      /*
      输出
      1000*/
      

      final不能修饰构造方法(构造器)