Java中Static关键字-Static定义代码块-单例设计模式

告别软件轮询!用STM32G474的COMP比较器实现纳秒级硬件过压保护(CubeMX配置详解) 本文详细介绍了如何利用STM32G474的COMP比较器实现纳秒级硬件过压保护,通过CubeMX配置详解,展示了硬件比较器相比传统软件轮询方案在响应时间、CPU占用和可靠性等方面的显著优势。文章还提供了实战配置流程和优化技巧,帮助工程师快速构建高效的硬件保护系统。 阅读详情

面向对象的进阶

面向对象进阶的第一篇, 主要讲解内容如下:

  • static关键字 : 开发中如何定义一个共享的信息,给所有对象共享访问,如在线人数信息等。
  • 单例设计模式 : 有些类只需要一个对象就可以了,如任务管理器对象,如何实现一个类只能对外产生同一个对象
  • 面向对象三大特征-继承 : 大量角色类的属性和行为存在重复代码,如果把一类的角色信息进行优化,提升代码复用,降低代码冗余

静态关键字:static

static修饰成员变量

static是静态的意思,可以修饰成员变量和成员方法。

static修饰成员变量表示该成员变量只在内存中只存储一份,可以被共享访问、修改。

<pre class="prettyprint hljs java" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class  User  { 
        // 静态成员变量 
        public static int onlineNumber= 161;
    // 实例成员变量
    private String name;
        private int age;
    …
}</pre>

成员变量可以分为2类:

  1. 静态成员变量
  2. 实例成员变量

静态成员变量

静态成员变量 : 有static修饰,属于类,与类加载时一起加载一次

常表示如在线人数信息、等需要被共享的信息,可以被共享访问。

<pre class="prettyprint hljs php" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class  User  { 
    // 静态成员变量
        public static String onlineNumber= 161;
}</pre>

静态成员变量访问方式有两种:

通过类访问(推荐): 类名.静态成员变量

<pre class="prettyprint hljs cs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public  static  void  main(String[] args)  { 
        // 类名.静态成员变量
        System.out.println(User.onLineNumber);
}</pre>

通过实例对象访问(能够访问但不推荐): 对象.静态成员变量

<pre class="prettyprint hljs cs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public  static  void  main(String[] args)  { 
        // 对象.静态成员变量
        User u1 = new User();
        System.out.println(u1.onLineNumber);
}</pre>

实例成员变量

实例成员变量 : 无static修饰,存在于每个对象中, 属于每一个实例对象

常表示姓名name、年龄age、等属于每个对象的信息。

<pre class="prettyprint hljs java" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class  User  { 
        // 实例成员变量 
        private String name;
        private int age;
}</pre>

实例成员变量的访问方式只有一种, 访问格式: 对象.实例成员变量

<pre class="prettyprint hljs cs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public  static  void  main(String[] args)  { 
        // 对象.实例成员变量
        User u1 = new User();
        u1.name = "chenyq";
        u1.age = 18;
        System.out.println(u1.name);
        System.out.println(u1.age);
}</pre>

static修饰成员方法

刚刚我们学习了static修饰成员变量, 那修饰成员方法呢?

之前我们定义的方法有的有static修饰,有的是没有的,它们有什么不同

<pre class="prettyprint hljs cs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 没有用static修饰
public  void  run(){ 
        System.out.println(name +"正在好好学习,天天向上~~");
}

// 有用static修饰
public  static  int  getMax(int a ,  int b){ 
        return a > b ? a : b;
}</pre>

成员方法和成员变量相似, 也是分为两类:

  1. 静态成员方法
  2. 实例成员方法

实例成员方法 (有static修饰,属于类)

建议用类名访问(推荐),也可以用对象访问(同样不推荐)。

表示 对象自己的行为的 ,且方法中需要访问实例成员的,则该方法必须申明成实例方法。

<pre class="prettyprint hljs typescript" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class Student { 
    // 对象的成员变量
    private String name;
    private Number age;
    // 定义有参构造器
    public Student (String name, Number age) { 
        this.name = name;
        this.age = age;
    }

    // 定义实例成员方法
    public void study() { 
        // 实例成员方法可以访问对象成员变量
        System.out.println(name + "正在学习");
    }

    public static void main(String[] args) { 
        // 调用实例方法: 对象.实例方法
        Student stu = new Student("chenyq", 18);
        stu.study(); // chenyq正在学习
    }
}</pre>

静态成员方法 (无static修饰,属于对象)

只能用对象触发访问。

如果该方法是 以执行一个公用功能为目的 ,则可以申明成静态方法。

<pre class="prettyprint hljs cs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class Student { 
    // 对象的成员变量
    private String name;
    private Number age;

     // 定义静态成员方法
     public  static  int  getMax(int a,  int b)  { 
        if (a > b) return a;
        return b;
     }

    public  static  void  main(String[] args)  { 
        // 调用静态方法: 类.静态方法
        // 同一个类中访问静态成员, 可以省略不写
        System.out.println(getMax(10, 20)); // 省略
        System.out.println(Student.getMax(10, 20));
    }
}</pre>

静态方法定义工具类

工具类:

工具类中定义的都是一些静态方法,每个方法都是以完成一个共用的功能为目的。

现状问题分析:

在企业的管理系统中,通常需要在一个系统的很多业务处使用验证码进行防刷新等安全控制。

如果登录和注册等多处地方都存在验证码逻辑,就会导致同一个功能多处开发,会出现代码重复度过高。

工具类的好处:

一是 调用方便 ,二是 提高了代码复用 (一次编写,处处可用)

我们在工具类使用静态成员方法, 方便调用节约内存

实例方法需要创建对象调用,此时用对象只是为了调用方法,这样只会浪费内存。

工具类的定义注意:

建议将工具类的构造器进行私有,不允许创建对象。

里面都是静态方法,直接用类名访问即可, 工具类无需创建对象, 。

<pre class="prettyprint hljs java" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class  ArraysUtils  { 
    // 工具类构造器私有化处理
    private  ArraysUtils()  { 

    }
}</pre>

我们来试着定义一个数组工具类, 需求如下:

需求:在实际开发中,经常会遇到一些数组使用的工具类。请按照如下要求编写一个数组的工具类:ArraysUtils

思路分析:

我们知道数组对象直接输出的时候是输出对象的地址的,而项目中很多地方都需要返回数组的内容,请在ArraysUtils中提供一个工具类方法toString,用于返回整数数组的内容,返回的字符串格式如:[10, 20, 50, 34, 100]( 只考虑整数数组,且只考虑一维数组 )

<pre class="prettyprint hljs java" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class  ArraysUtils  { 
    // 将构造器设为私有
    private  ArraysUtils()  { 

    }

    public  static  String  toString(int[] arr)  { 
        String showArr = "[";
        for (int i = 0; i < arr.length; i++) { 
            showArr += arr[i];
            showArr += (i == arr.length -1 ? "]" : ", ");
        }
        return showArr;
    }
}</pre>

经常需要统计平均值,平均值为去掉最低分和最高分后的分值,请提供这样一个工具方法getAerage,用于返回平均分。( 只考虑浮点型数组,且只考虑一维数组 )

<pre class="prettyprint hljs java" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class  ArraysUtils  { 
    // 将构造器设为私有
    private  ArraysUtils()  { 

    }

    public  static  String  toString(int[] arr)  { 
        String showArr = "[";
        for (int i = 0; i < arr.length; i++) { 
            showArr += arr[i];
            showArr += (i == arr.length -1 ? "]" : ", ");
        }
        return showArr;
    }

    public  static  double  getAerage(double[] arr)  { 
        double max = arr[0];
        double min = arr[0];
        double sum = 0;
        for (int i = 0; i < arr.length; i++) { 
            if (max < arr[i]) max = arr[i];
            if (min > arr[i]) min = arr[i];
            sum += arr[i];
        }
        return  (sum - max - min) / (arr.length - 2);
    }
}</pre>

定义一个测试类TestDemo,调用该工具类的工具方法,并返回结果。

定义好一个工具类, 在其他地方

<pre class="prettyprint hljs cs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class TestDemo { 
    public  static  void  main(String[] args)  { 
        int[] nums = { 10, 20, 30, 40};
        // 调用toString方法, 并对返回结果打印
        System.out.println(ArraysUtils.toString(nums)); // [10, 20, 30, 40]

        double[] score = { 2.0, 1.8, 1.7, 1.9, 1.6};
        // 调用getAerage方法, 并对返回结果打印
        System.out.println(ArraysUtils.getAerage(score)); // 1.8
    }
}</pre>

static访问注意事项:

静态方法只能访问静态的成员,不可以直接访问实例成员。

实例方法可以访问静态的成员,也可以访问实例成员。

静态方法中是不可以出现this关键字的。

Static定义代码块

静态代码块和构造代码块

代码块概述

代码块是类的5大成分之一(成员变量、构造器,方法,代码块,内部类),定义在类中方法外。

在Java类下,使用 { } 括起来的代码被称为代码块 。

代码块分为 :

  1. 静态代码块
  2. 动态代码块

静态代码块:

格式: static{}

特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发、只执行一次

使用场景:在类加载的时候做一些静态数据初始化的操作,以便后续使用。

<pre class="prettyprint hljs cs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class TestDemo01 { 
    // 当类加载的时候, static中的代码块会自动执行一次
    static { 
        System.out.println("静态代码块与类一起加载的代码块, 自动触发一次");
    }

    public  static  void  main(String[] args)  { 

    }
}</pre>

构造代码块(了解,用的少):

格式: {}

特点:每次创建对象,调用构造器执行时,都会执行该代码块中的代码,并且在构造器执行前执行

使用场景:初始化实例资源。

<pre class="prettyprint hljs cs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class TestDemo01 { 
    { 
        System.out.println("构造代码块与对象一起加载的代码块, 自动触发执行");
    }

    // 定义构造器
    public  TestDemo01()  { 
        System.out.println("构造器执行了");
    }

    public  static  void  main(String[] args)  { 
        // 创建第一个对象
        new TestDemo01();
        // 创建第二个对象
        new TestDemo01();
    }
}</pre>

打印结果如下:

我们发现, 构造代码块会比构造器先执行

由于构造代码块与对象一起加载, 索引每创建一个对象, 构造代码块中的内容都会执行一次

静态代码块的小案例练习

相信大家都玩过斗地主游戏, 现在我们有如下一个需求

需求:

斗地主游戏在启动游戏房间的时候,应该提前准备好54张牌,后续才可以直接使用这些牌数据。

我们来完成这个提前准备好54张牌的功能

分析:

该房间只需要一副牌。

定义一个静态的ArrayList集合存储54张牌对象,静态的集合只会加载一份。

在启动游戏房间前,应该将54张牌初始化好

当系统启动的同时需要准备好54张牌数据,此时可以用静态代码块完成。

<pre class="prettyprint hljs cs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class StaticCodeDemo { 
    // 定义静态成员变量
    public static ArrayList<String> cards = new ArrayList<>();

    // 使用静态代码块对静态资源cards进行初始化
    static { 
        String[] colors = { "♥", "♣", "♠", "♦"};
        String[] nums = { 
                "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"
        };

        for (int i = 0; i < nums.length; i++) { 
            for (int j = 0; j < colors.length; j++) { 
                cards.add(colors[j] + nums[i]);
            }
        }

        // 添加大小王
        cards.add("大王");
        cards.add("小王");
    }

    public  static  void  main(String[] args)  { 
        // 打印静态代码块查看效果
        System.out.println(cards);
    }
}</pre>

Static单例设计模式

參单例模式介绍

介绍单例模式之前, 我们先说一说什么是设计模式

设计模式(Design pattern):

开发中经常遇到一些问题,一个问题通常有n种解法的,但其中肯定有一种解法是最优的

这个最优的解法被人总结出来了,称之为设计模式。

设计模式有20多种,对应20多种软件开发中会遇到的问题,学设计模式主要是学2点:

  • 第一:这种模式用来解决什么问题。

  • 第二:遇到这种问题了,该模式是怎么写的,他是如何解决这个问题的。

单例模式:

可以保证系统中,应用该模式的这个类永远只有一个实例,即 一个类永远只能创建一个对象 。

例如任务管理器对象我们只需要一个就可以解决问题了,这样可以节省内存空间。

单例的实现方式有很多, 这篇我主要讲解以下两种单例模式:

饿汉单例模式。

懒汉单例模式。

饿汉单例模式

饿汉单例设计模式 : 在用类获取对象的时候,对象已经提前为你创建好了。

设计步骤:

<pre class="prettyprint hljs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">1.定义一个类,把构造器私有, 让外界无法创建对象。
2.定义一个静态变量, 用于存储创建出来的对象
</pre>
<pre class="prettyprint hljs java" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// 1.定义一个单例类
public class  SingleInstance1  { 
    // 3.定义一个静态成员变量, 用于储存一个对象
    public static SingleInstance1 instance1 = new SingleInstance1();
    // 2.将类的构造器设置为私有构造器
    private  SingleInstance1()  { 

    }
}</pre>

我们在通过另一个类中, 多次通过 SingleInstance1.instance1 获取对象也只会获取一次对象

这是因为类和静态成员变量一起加载, 且只加载一次, 所以只会获取到一个对象

<pre class="prettyprint hljs cs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class Test { 
    public  static  void  main(String[] args)  { 
        SingleInstance1 sin1 = SingleInstance1.instance1;
        SingleInstance1 sin2 = SingleInstance1.instance1;
        // 获取两次得到的是同一个对象
        System.out.println(sin1 == sin2); // true
    }
}</pre>

讀懒汉单例模式

懒汉单例设计模式 : 在真正需要该对象的时候,才去创建一个对象(延迟加载对象)。

设计步骤:

<pre class="prettyprint hljs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">1.定义一个类,把构造器私有。
2.定义一个静态变量存储一个对象。
3.提供一个返回单例对象的方法
</pre>
<pre class="prettyprint hljs java" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class  SingleInstance2  { 
    // 2.定义一个静态变量, 用于存储一个对象, 但是不初始化对象
    public static SingleInstance2 instance2;

    // 1.定义一个类, 把构造器私有
    public  SingleInstance2()  { 

    }

    // 3.提供一个返回单例对象的方法
    public  static  SingleInstance2  getObject()  { 
        if (instance2 == null) return instance2 = new SingleInstance2();
        return instance2;
    }
}</pre>

我们测试一下, 在另一个类中, 多次通过 SingleInstance1.getObject 获取对象, 是否只会获取一次对象

<pre class="prettyprint hljs cs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class Test { 
    private  static  void  main(String[] args)  { 
          SingleInstance2 sin1 =  SingleInstance2.getObject();
          SingleInstance2 sin2 =  SingleInstance2.getObject();
          System.out.println(sin1 == sin2); // true
    }
}</pre>

饿汉单例模式和懒汉单例模式区别对比:

饿汉单例模式和懒汉单例模式各有优缺点

  • 从第一次获取对象速度里来看: 饿汉单例模式的速度比懒汉单例模式快

  • 从内存资源来看: 饿汉单例模式有可能会浪费资源, 而懒汉单例模式不会

     

linux系统下XDMA驱动的安装与测试问题总结 先看两个常见的问题。一个是驱动安装问题,一个是驱动测试错误;error 512 能识别PCIE的设备,但是The kernel modle installed correctly, but no devices were recognized. 阅读详情

相关推荐

模板匹配加速之金字塔分层搜索

图像金字塔是一种多分辨率图像表示方法,它通过一系列逐渐缩小或放大的图像来表示原始图像的不同尺度。高斯金字塔(Gaussian Pyramid):通过不断下采样(降采样)生成更小的图像。拉普拉斯金字塔(Laplacian Pyramid):通过高斯金字塔和差分操作生成一组残差图像。在模板匹配中,我们主要使用高斯金字塔来实现多尺度匹配。金字塔灰度模板匹配通过多尺度搜索策略,在保持较高准确率的同时显著提升匹配速度,尤其适用于:高分辨率图像处理实时检测系统移动端设备等资源受限场景。

weixin_44969144的博客 1734

Java-案例练习:定义数组工具类

需求: 在实际开发中,经常会遇到一些数组使用的工具类。请按照如下要求编写一个数组的工具类:ArraysUtils ①::我们知道数组对象直接输出的时候是输出对象的地址的,而项目中很多地方都需要返回数组的内容,请在ArraysUtils中提供一个工具类方法toString,用于返回整数数组的内容,返回的字符串格式如:[10,20,50,34,100](只考虑整数数组,且只考虑一维数组) ②:定义一个测试类TestDemo,调用该工具类的工具方法,并返回结果。 工具类: priv...

weixin_52309279的博客 1830

virtualbox虚拟机里面最顶部没有控制、设置和帮助等选项

无意中操作,导致virtualbox虚拟机里面最顶部没有控制,设置和帮助选项  virtualbox虚拟机窗口显示如下如: 如何设置,窗口显示如下图所示呢: virtualbox虚拟机窗口模式显示设置,切换可以通过如下图所示操作进行切换: PS:一定要是右边的Ctrl+C

WEL测试 8780

定义数组工具类

需求:在实际开发中,经常会遇到一些数组使用的工具类请按照如下要求编写一个数组的工具类:ArrayUtil。返回的字符串格式如:[10,20,50,34,100](只考虑整数数组,且只考虑一维数组)提供一个工具方法getAerage,用于返回平均分。(只考虑浮点型数组,且只考虑一维数组)定义一个测试类TestDemo,调用该工具类的工具方法,并返回结果。提供一个工具类方法printArr,用于返回整数数组的内容。

2301_80177792的博客 629

基于资源预测的Agent弹性伸缩:在成本与响应延迟间寻找最佳平衡点

手动伸缩:完全由运维人员人工调整副本数或服务器数量,效率极低,现在基本只用于极小规模的业务。反应式伸缩:基于当前实时监控指标触发伸缩规则,比如CPU利用率超过70%就加2个副本,是目前应用最广泛的方案,典型代表是K8s HPA、KEDA。预测式伸缩:基于历史时序数据预测未来的负载,提前进行伸缩,解决反应式伸缩的滞后性问题,典型代表是AWS Predictive Scaling、阿里云预测式HPA。智能Agent伸缩。

SuperAGI2025 135

从原理到代码:一文搞懂LFM信号脉冲压缩在Matlab中的实现

本文深入解析了LFM信号脉冲压缩的核心原理与Matlab实现方法。从线性调频信号的数学表达、时频特性入手,详细讲解了如何构建多目标回波仿真环境,并重点阐述了匹配滤波器的频域实现算法。文章提供了完整的、可运行的Matlab代码,涵盖信号生成、噪声添加、脉冲压缩及性能评估等关键步骤,并探讨了加窗处理、参数选择等工程实践中的考量,为雷达信号处理的学习与实践提供了清晰指南。

weixin_29063035的博客 415

【Java基础笔记】第十四章 static静态关键字

目录前言第十四章 static静态关键字14.1 static关键字的作用14.2 static修饰成员变量14.2.1 静态成员变量14.2.2 实例成员变量14.2.3 static修饰成员变量的内存原理14.3 static修饰成员方法14.3.1 静态成员方法14.3.2 实例成员方法14.3.3 static修饰成员方法的内存原理14.4 static实际应用14.4.1 工具类14.4.2 工具类原理和延伸【static应用案例1】设计验证码工具类【static应用案例2】设计数组工具类 前言

Silence的学习小站 804

【异常】解决 Claude Code 及第三方插件提示 “API Error: 404“ 的配置修复指南

在使用 Claude 相关的 CLI 工具(如)或 IDE 插件进行开发辅助时,配置错误的模型参数是导致连接失败的常见原因。本文将针对这一典型报错进行复盘与解决。

奶爸的编程之路,也就一周冷个三天 7750

JAVA练习题33:定义数组工具类(static训练)

需求:在实际开发中,经常会遇到一些数组使用的工具类。请按照如下要求编写一个数组的工具类:ArrayUtil要求:提供一个工具类方法printArr,用于返回整数数组的内容返回的字符串格式如:[1,2,3,4 ] (只考虑整数数组,且只考虑一维数组)提供这样一个工具方法getAverage,用于返回平均分(只考虑浮点型数组,且只考虑一维数组)定义一个测试类TestDemo,调用该工具类的工具方法,并返回结果。

m0_46457497的博客 931

基于 Langchain 开发一个完整的支持多轮数据分析(直连 mysql 数据,多表综合分析 SQL 取数,数据分析,报表生成)ChatBI 系统(前后端完整实现源代码)

ChatBI系统开发摘要 本文介绍了基于Langchain的多轮数据分析ChatBI系统开发方案。该系统支持MySQL数据库连接,提供多表分析、SQL查询、数据分析和报表生成功能。系统采用前后端分离架构:前端使用React+Ant Design+ECharts实现交互界面;后端基于FastAPI搭建服务,集成Langchain处理自然语言到SQL的转换;核心技术栈还包括SQLAlchemy、Pandas和Matplotlib。 系统核心模块包括: 数据库连接层:使用SQLAlchemy管理MySQL连接 L

AI天才研究院 818

基于YOLOv5/v8/v10的垃圾分类识别系统:设计实现与性能优化(附代码+数据集)

做完这个毕设,你已经掌握了从数据准备、模型训练到界面开发的全流程。把模型部署到树莓派上,做个真正的“智能垃圾桶”硬件装置;加入语音提示功能,检测到垃圾后自动语音播报类别;试试融合多个YOLO模型的优势,让分类精度再上一个台阶。按照这个教程一步步做,你的毕设不仅能顺利完成,还能做出很多亮点。要是过程中遇到啥问题,别慌,慢慢琢磨或者咱们一起聊聊,肯定能把这个毕设做成让你满意的作品。

know_F0727的博客 464

java练习案例--定义数组工具类

利用简单案例学习定义与调用数组工具类---java

小库里的学习记录 1667

【华为OD机试】真题-小明减肥(Java)

摘要:题目要求从n个可选运动中选取k个,使其卡路里总和等于目标值t,统计可行方案数。输入包含运动数量n、目标t、选择数量k及卡路里数组。采用DFS回溯算法,通过剪枝优化(提前终止无效分支),分别处理选择/不选当前运动的情况。当遍历完所有运动且满足条件时计数。示例输入"4 3 2"和"1 2 3"时,输出2(对应两种选择组合)。Java实现通过递归完成搜索,最终输出符合条件的方案总数。(149字)

u014481728的博客 287

static关键字整理

黑马视频基础加强第一天课程总结

weixin_68151004的博客 655

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Java中static关键字的作用

static关键字主要有两种作用: 第一,为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。 第二,实现某个方法或属性与类而不是对象关联在一起 具体而言,在Java语言中,static主要有4中使用情况:成员变量、成员方法、代码块和内部类 (1)static成员变量: Java类提供了两种类型的变量:用static关键字修饰的静态变量和不用static关键字修饰的实例变量。静态变量属于类,在内存中只有一个复制,只要静态变量所在的类被加载,这个静态变量就会被分配空间,因此就可以被使用了。对静态

Dalish_的博客 3525

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Java基础 -----static、final、main、单例设计模式、代码块、抽象类、接口、内部类

文章目录1、static关键字1.1、static修饰属性1.2、类变量 vs 实例变量内存解析1.3、static修饰方法2、单例设计模式3、main方法4、代码块5、final关键字6、抽象类与抽象方法7、接口8、内部类 1、static关键字 当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过 new 关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。 我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空

weixin_48751562的博客 694

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

java-面向对象4-代码块、static关键字和final关键字

目录前言1、关键字:static 前言 本文主要介绍java面向对象中static关键字 1、关键字:static static关键字的引入: 有时候希望无论是否产生了对象或无论产生了多少 对象的情况下,某些特定的数据在内存空间里只有一份。 java将static关键字修饰的成员称为类成员: 类属性:作为该类各个对象之间共享的变量。在设计类时,分析哪 些属性不因对象的不同而改变 类方法:如果方法与调用者无关,则这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用。 s

nmvc01的博客 213

static,单例设计模式,main方法,代码块

static,单例设计模式,main方法,代码块

m0_74012211的博客 668

static关键字和继承

来自拉钩教育-JAVA就业集训营 People类和测试类的实现 案列题目 编程实现People类的封装,特征有:姓名、年龄、国际,要求提供打印所有特征的方法。 编程试下PeopleTest类,main方法中使用有参方式构造两个对象并打印。 /* */ public class People { // 1.私有化成员变量,使用private关键字修饰 private String name; private int age; private String county; // 3

逃跑的浣熊 171

Java基础学习——代码块、static、final

前言 nskswl加油~ static static是一个修饰符,用于修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能。 static修饰:属性、方法、代码块、内部类 static修饰属性:静态变量(类变量): 1. 我们创建类类的多个对象,多个对象共享一个静态变量。当通过某个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过的。 2. static修饰属性的其他说明:静态变量随着类的加载而加载;静态变量的加载早于对象的创建;可以通过类名调用;由于类只会加载一次,则

qq_46438498的博客 178

重识Java第五天打卡----面向对象进阶1【static关键字、单例、继承】

static是静态的意思,可以用来修饰成员变量、成员方法。static修饰成员变量之后称为静态成员变量(or类变量),修饰方法之后称为静态方法(类方法)。static修饰后的成员变量,可以被类的所有对象共享(访问、修改)。............

qq_51032943的博客 214

Static关键字

Java static 关键字使用规则 static关键字主要有两种作用: 第一,为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。 第二,实现某个方法或属性与类而不是对象关联在一起 static主要有4中使用情况:成员变量、成员方法、代码块和内部类 (1)static成员变量: Java类提供了两种类型的变量:用static关键字修饰的静态变量和不用static关键字修饰的实例变量。静态变量属于类,在内存中只有一个复制,只要静态变量所在的类被加载,这个静态变量就会被分配空间,因此就可以被使

weixin_41075660的博客 185

【Java基础12】构造方法、this和static关键字、单例设计模式、对象的一对一关系

构造方法、this和static关键字、单例设计模式、对象的一对一关系

天赋决定上限,努力决定下限! 171

【Java基础】Java 中的 static 关键字

在 Java 的编程世界里,static关键字是一个非常重要且实用的特性。它就像是一把神奇的钥匙,能够改变变量、方法、代码块和内部类的性质和行为。static关键字在 Java 中是一个非常强大的工具,它可以修饰成员变量、成员方法、代码块和内部类,改变它们的性质和使用方式。静态变量和静态方法属于类本身,所有对象共享静态变量,通过类名可以直接调用静态方法。静态代码块在类加载时执行,用于初始化静态变量或执行一次性操作。静态内部类不依赖于外部类的实例,可以直接创建对象。

小李同学的博客 2304

Java中static关键字和代码块的学习

本文介绍了Java中static关键字的使用,即静态成员变量和成员方法以及使用,静态与非静态成员变量和方法的对比总结 Java中的代码块介绍与最后结合代码块和构造方法后的初始化代码执行顺序的练习

记录并分享学习编程时的知识点... 2180
下一篇: Java 的业务逻辑验证框架指的是?
Java_ttcd
博客等级 码龄4年 198粉丝 190原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值