• Java - static 关键字


    前言

    最近在阅读 《Java编程思想》 这本书,看到 static 关键字这一章节,本以为对于 static 关键字已经很了解了,没想到在又看了一遍之后,还是会有新的理解,特此记录一下。

    为什么要有 static

    我们定义了一个类,这个类描述了 一类具有共同特征的对象 的一些 特征行为,比如 鸟类 都有 翅膀,都会 翅膀 就是类的 属性 就是类的 方法,我们只有创建了一个对象,才能使用响应的方法,比如我们创建了一个 麻雀 对象,才能使用 麻雀 方法,并可以给 麻雀翅膀 属性赋值,比如 灰色的翅膀。也就是说我们只有创建了类的对象(使用 new 创建对象),才能使用类中定义的 属性方法

    以下两种情形,可以在不 new 对象的时候,使用相应的 属性方法

    • 只想用一个特定的存储区域来保存一个特定的数据(无论要创建多少对象或者说根本不创建对象)
    • 需要一个特殊的方法,不与类的任何对象关联,即使没有创建对象,也可以调用

    为满足以上两种需求,可以使用 static 关键字。一旦将 属性方法static 修饰,那么就不会跟类的任何对象再联系到一起,即使不创建对象也可以调用。

    在开发中的应用场景为:常量类工具类

    概述

    定义一个 static 修饰的属性:

    public class StaticTest {
    
        static int i = 10;
    }
    
    • 1
    • 2
    • 3
    • 4

    现在我们创建两个对象:

    StaticTest staticTest1 = new StaticTest();
    StaticTest staticTest2 = new StaticTest();
    System.out.println(staticTest1.i);	// 10
    System.out.println(staticTest2.i);	// 10
    
    • 1
    • 2
    • 3
    • 4

    从结果可以看出,两个对象的 i 值是相同的,因为他们引用的是同一片内存区域。

    StaticTest.i++;
    System.out.println(staticTest1.i);	// 11
    System.out.println(staticTest2.i);	// 11
    
    • 1
    • 2
    • 3

    有两种方法可以引用一个 static 变量,一种是通过对象引用,另一种是使用类名引用,也推荐使用类名引用,可以强调 static 关键字的本质。

    StaticTest.i
    
    • 1

    static 修饰类的属性:

    public class Color {
    
    	// 静态变量、静态属性
        public static String sun = "red";
    
    	// 实例变量
    	public String sea = "bule";
    
    	// getter setter
    	...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    通过上面的例子,我们知道 static 修饰的属性、方法、代码块、内部类等都是属于类的,非 static 的是属于对象的,只有创建对象的时候才能被调用

    也就是说静态的变量是共享的,创建了多个对象,如果静态变量可以被修改(不是 final),那么某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的

    • 实例变量
      需要依赖对象的创建而被初始化,每个对象都独立拥有一套类中的非静态属性。当修改其中一个对象的非静态属性时,不会导致其他对象中同样的属性值的修改。
    public static void main(String[] args) {
    	Color color = new Color();
        Color color2 = new Color();
        color.setSea("green");
        System.out.println(color2.getSea());	// blue
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 静态变量
      静态变量是类的属性,不是对象的变量(属性),调用时直接通过类名调用,在类加载的时候已经初始化,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时是修改过的。

    static 关键字的应用场景

    1、静态变量

    静态变量属于类,内存中只有一个实例,当类被加载时,就会为该静态变量分配内存空间。存储在 方法区 中,一般情况下不会被回收,除非 JVM 退出。

    在这里插入图片描述

    比如:BigDecimal 类中 1~10 时经常需要使用的,我们开发过程中需要使用 new BigDecimal("10") 创建,BigDecimal 直接提供了静态变量,当类被加载的时候,会初始化到内存中,避免了频繁的创建对象。

    2、静态方法

    常用于各种 工具类

    3、静态代码块

    参考 Java - 代码块 这篇文章中的静态代码块部分

    参考 Java - 单例模式详解 中的使用静态代码块初始化单例对象

    4、静态内部类

    参考 Java - 单例模式详解 中的使用静态内部类创建单例对象

    5、静态导入

    import static com.example.constant.CacheConsts.*;
    
    • 1

    静态导入是 JDK 1.5 之后新加的功能,比如有一个常量类:CacheConsts

    • 在不使用 static 导入的情况下,我们引用其中的常量:
    public void init() {
    	CacheConsts.USER_KEY;
    	CacheConsts.ORDER_KEY;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 在使用 static 导入的情况下,可以省略类名直接引用,简化一部分代码:
    public void init() {
    	USER_KEY;
    	ORDER_KEY;
    }
    
    • 1
    • 2
    • 3
    • 4

    但是在引入工具类的时候,不建议使用这种方式,比如:

    public void init() {
    	isBlank(str);
    	isNull(str);
    	getOrderNo();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这种情况下,如果不指定具体类名,也会导致代码可读性变差,所以项目中使用不使用,还是要具体情况具体分析。

  • 相关阅读:
    深度学习实践3:多层感知机
    Docker-概念及配置(超详细)
    C语言 二维数组和函数综合编程练习
    uniapp开发微信小程序获取用户手机号
    微擎模块 志汇超级外卖餐饮小程序5.7.5开源版 后台模块+前端小程序源码
    “could not open `CProgram FilesJavajre7libamd64jvm.cfg”问题解决办法
    Mybatis04关联关系映射
    常见自动化测试工具集合
    acwing算法基础之基础算法--求逆序对的数目
    STM32链接脚本
  • 原文地址:https://blog.csdn.net/qiaohao0206/article/details/125522016