单例设计模式,final,
- 设计模式就是在大量的实践中总结和理论化之后优选的代码结构,编程风格,以及解决问题的思考方法。设计模式就像经典的棋谱,不同的棋局,我们用不同的棋谱,免得我们自己在思考和摸索。
- 单例模式:类的单例模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法
- 单例模式(饿汉式,懒汉式)
- 饿汉式:有可能造成资源的浪费
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对象类加载的时候就创建好了,虽然你还没打算用,比较着急
-
懒汉式:使用了才创建
-
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 + '\\'' +'}';} }
-
-
两者区别
-
创建时机不同,饿汉式在类加载,懒汉式在使用时才创建。
-
饿汉式不存在线程安全问题,懒汉式存在线程安全问题
-
饿汉式有可能浪费资源,懒汉式没有
-
-
final关键字
-
final可以修饰类,属性,方法和局部变量
-
当不希望类被继承时,可以用final修饰
-
不希望父类的某个方法被子类覆盖/重写时,可以用final关键字修饰
-
当不希望类的某个属性的值被修改,可以final修饰public final int n1=100;
-
不希望局部变量被修改用final
-
-
final注意事项
-
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来命名。
-
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不能修饰构造方法(构造器)
-