【Java底子】10章、单例模式、final关键字的利用本领和利用细节、单例模式-懒汉式、单例模式-饿汉式【3】 [复制链接]
发表于 2025-10-2 10:54:40 | 显示全部楼层 |阅读模式
跟着一位很锋利的老师学完了java底子,现开始举行javaSE复盘总结知识点,盼望可以给java底子单薄的友友提供一点参考,一起学习Java低级知识,共同进步,打好底层逻辑底子,爱上Java编程❤️❤️❤️
(本文章中知识点如有差别的见解,欢迎品评区留言)



1、单例模式

11、根本先容

1.1.1、什么是操持模式




  • 什么是单例模式
单例(单个的实例)

  • 所谓类的单例操持模式,就是采取肯定的方法包管在整个软件体系中,对某个类只能存在一个对象实例,而且该类只提供一个取得对象实例的方法。
  • 单例模式有两种方式:(1)饿汉式 (2)懒汉式

1.1.2、应用实例

1.1.2.1、单例模式-饿汉式

  1. package com.fhsedu.single_;
  2. //有一个类,GirFriend
  3. //只能有一个女朋友
  4. class GirlFriend {
  5.     private String name;
  6.     //为了能够在静态方法中,返回gf对象,需要将其修饰为static
  7.     private static GirlFriend  gf = new GirlFriend("小红红");
  8.     //如何保障我们只能创建一个GirlFriend对象
  9.     //步骤【单例模式-饿汉式】
  10.     //1、将构造器私有化
  11.     //2、在类的内部直接创建
  12.     //3、提供一个公共static方法,返回gf对象
  13.     private GirlFriend(String name) {
  14.         this.name = name;
  15.     }
  16.     public static GirlFriend getInstance() {
  17.         return gf;
  18.     }
  19.     @Override
  20.     public String toString() {
  21.         return "GirlFriend{" +
  22.         "name='" + name + '\'' +
  23.         '}';
  24.     }
  25. }
  26. public class SingleTon01 {
  27.     public static void main(String[] args) {
  28.         //通过方法可以获取对象
  29.         GirlFriend instance1 = GirlFriend.getInstance();
  30.         System.out.println(instance1);
  31.         GirlFriend instance2 = GirlFriend.getInstance();
  32.         System.out.println(instance2);
  33.         System.out.println(instance1.hashCode() + "  " + instance2.hashCode());//相同
  34.     }
  35. }
复制代码



  • 饿汉式办理有大概造成创建了对象,但是没有利用,带来的弊端
1.1.2.2、单例模式-懒汉式

   不管是懒汉式照旧饿汉式都是在类中都是创建一个详细的实例
  代码演示
  1. package com.fhsedu.single_;
  2. //演示懒汉模式的单例
  3. //希望在程序运行过程中,只能创建一个Cat对象
  4. class Cat {
  5.     private String name;
  6.     public static int n1 = 999;
  7.     private static Cat cat;
  8.     //步骤
  9.     //1、仍然让构造器私有化
  10.     //2、定义一个static静态属性对象
  11.     //3、提供一个public的static方法,可以返回一个Cat对象
  12.     //4、懒汉式,只有当用户使用getInstance时,才返回cat对象,后面再次调用时会返回上次创建的cat对象
  13.     //      从而保证了单例
  14.     private  Cat (String name) {
  15.             this.name = name;
  16.     }
  17.     public static Cat getInstance() {
  18.         System.out.println("构造器被调用...");
  19.         if (cat == null){//如果没有创建cat对象
  20.             cat = new Cat("小可爱");
  21.             n1++;
  22.         }
  23.         return cat;
  24.     }
  25.     @Override
  26.     public String toString() {
  27.         return "Cat{" +
  28.         "name='" + name + '\'' +
  29.         '}';
  30.     }
  31. }
  32. public class SingleTon02 {
  33.     public static void main(String[] args) {
  34.         //此时初始化为 999
  35.         System.out.println(Cat.n1);
  36.         //Cat为null 执行 new Cat  和  n++
  37.         Cat cat1 = Cat.getInstance();
  38.         //此时  n == 1000
  39.         System.out.println(cat1);//默认是null
  40.         System.out.println(cat1 + "" + cat1.hashCode());
  41.         //再次调用getInstance,此时还是之前的那只猫吗?
  42.         //初始化第2只猫,但是指向的还是之前的那只
  43.         Cat cat2 = Cat.getInstance();
  44.         //n1 == 1000
  45.         System.out.println(Cat.n1);
  46.         System.out.println(cat2 + "" + cat2.hashCode());
  47.         Cat cat3 = Cat.getInstance();
  48.         System.out.println(cat3 + "" + cat3.hashCode());
  49.         //n1 == 1000
  50.         System.out.println(Cat.n1);
  51.     }
  52. }
复制代码


饿汉式细节:
此时没有创建对象



(Runtime中的单例模式-饿汉式)
1.1.2.3、区别

饿汉式存在题目:在类加载时间就创建,大概存在资源浪费题目
懒汉式存在题目:线程安全题目

4.1.2.4、小结


  • 单例模式的两种起首方式1)饿汉式 2)懒汉式
  • 饿汉/懒汉式创建的过程
  • 要求,可以自己独立写出单例模式
2、final关键字


   演示:如果我们以为这个类很告急不盼望被继续和重写
  

代码演示:


  • 拒接继续本类
  • 拒接重写父类方法
  • 拒绝修改本类中的属性
  1. package com.fhsedu.final_;
  2. public class Final01 {
  3.     public static void main(String[] args) {
  4.         E e = new E();
  5.         //        e.TAX_RATE = 200;//
  6.     }
  7. }
  8. //如果我们要求A类不能被其他类继承
  9. //可以使用final修饰 A类
  10. final class A {}
  11. //class B extends A{}
  12. class C{
  13.     //如果我们要求hi不能被子类重写
  14.     //可以使用final修饰 hi方法
  15.     public final void hi() {
  16.     }
  17. }
  18. class D extends C{
  19.     /*@Override
  20.     public void hi() {
  21.         System.out.println("重写了C类的hi方法..");
  22.     }*/
  23. }
  24. //当不希望类的某个属性的值被修改
  25. class E{
  26.     public final double TAX_RATE = 0.08;
  27. }
  28. //当不希望某个局部变量被修改,可以使用final
  29. class F{
  30.     public void cry() {
  31.         //这时,NUM 也称为局部常量
  32.         final double NUM = .01;
  33.         //        NUM = .9;
  34.         System.out.println("NUM=" + NUM);
  35.     }
  36. }
复制代码
2.1、final细节

   final修饰的常量一样平常为大写
  final修饰常量时,必须初始化属性
  final可以实例化但不能继续(类)
  2.1.1、细节一


(把握)
2.1.2、细节二



  • 不要多此一举
  1. final class AAA{
  2.     //一般来说,如果一个类已经是final类了,就没有必要将方法设置为final方法了
  3.     //public final void hi(){}//多此一举,已经不能继承该类了,可定不能重写该方法
  4. }
复制代码
有无final做对比:
看此时没有加载static静态代码块的内容,底层举行了优化:


  • 没有加上final:

(输出n1 和 static中的内容)


  • 加上final后

(没有了static的内容)
   缘故原由:
类加载的五个阶段:载入、验证、准备、分析 和 初始化 阶段
静态属性和静态代码块是按照次序实行的;此时静态属性先加载
又由于静态属性之前有final,以是在类加载的准备阶段就被赋予了界说的值,而不实行分析和初始化的阶段。
因此静态代码块不再实行(原来在初始化阶段实行)
  

  • detail 02

//包装类,String 是final类,不能继续类
2.2、finalExercise


  1. package com.fhsedu.final_;
  2. public class FinalExercise01 {
  3.     public static void main(String[] args) {
  4.         Circle circle = new Circle(5.0);
  5.         System.out.println( "面积=" + circle.calArea());
  6.     }
  7. }
  8. class Circle{
  9.     private double radius;
  10.     private final double PI;//= 3.14
  11.     //构造器
  12.     public Circle(double radius) {
  13.         //        PI = 3.14;//可以在这三个位置初始化,但是只能初始化一次
  14.         this.radius = radius;
  15.     }
  16.     {
  17.         PI = 3.14;
  18.     };
  19.     public double calArea() {
  20.         return PI * radius * radius;
  21.     }
  22. }
复制代码


  • 题二


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表