1. 使用方法

static 是 java 中非常重要的一个关键字,而且它的用法也很丰富,主要有四种用法:

  1. 用来修饰成员变量,将其变为类的成员,从而实现所有对象对于该成员的共享;
  2. 用来修饰成员方法,将其变为类方法,可以直接使用“类名.方法名”的方式调用,常用于工具类;
  3. 静态块用法,将多个类成员放在一起初始化,使得程序更加规整,其中理解对象的初始化过程非常关键;
  4. 静态导包用法,将类的方法直接导入到当前类中,从而直接使用“方法名”即可调用类方法,更加方便。

2. 特殊含义

2.1. 静态变量

按照是否静态的对类成员变量进行分类可分两种:一种是被 static 修饰的变量,叫静态变量或类变量;另一种是没有被 static 修饰的变量,叫实例变量。

两者的区别是:

对于静态变量在内存中只有一个拷贝(节省内存),JVM 只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)。

对于实例变量,没创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响(灵活)。

static 成员变量的初始化顺序按照定义的顺序进行初始化。static 不可以修饰局部变量;

所以一般在需要实现以下两个功能时使用静态变量:
在对象之间共享值时
方便访问变量时

2.2. 静态方法

静态方法的好处就是不用生成类的实例就能直接调用,可以这样理解使用 static 修饰的成员不再归对象所以,而是属于类 可以理解为是共有的,也就说只要通过类名就可以访问,不需要耗费资源反复创建对象,因为在程序第一次加载的时候就已经在内存中了,直到程序结束该内存才会释放。如果不是 static 修饰的成员在使用完之后该内存就会被回收,所以说 static 要慎用,根据实际情况而定

如果这个方法是作为一个工具来使用,就声明为 static,不用 new 一个对象出来就可以使用了,比如连接到数据库,我声明一个 getConnection() 的方法,就定义为静态的,因为连接到数据库不是某一个对象所特有的。它只作为一个连接到数据库的工具。至于提高效率的也未 必,要看具体的方法的用处,去定义这个方法是不是静态的。

2.3. 静态代码块

static 代码块也叫静态代码块,是在类中独立于类成员的 static 语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM 加载类时会执行这些静态的代码块,如果 static 代码块有多个,JVM 将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次,所以说 static 块可以用来优化程序性能。

2.4. 静态代码块和静态方法的区别

2.4.1. 执行

静态代码块是自动执行的;
静态方法是被调用的时候才执行的.

2.4.2. 场景

静态方法:如果我们在程序编写的时候需要一个不实例化对象就可以调用的方法,我们就可以使用静态方法,具体实现是在方法前面加上 static

在静态方法里只能直接调用同类中其他的静态成员(包括变量和方法),而不能直接访问类中的非静态成员。这是因为,对于非静态的方法和变量,需要先创建类的实例对象后才可使用,而静态方法在使用前不用创建任何对象。(备注:静态变量是属于整个类的变量而不是属于某个对象的)

静态方法不能以任何方式引用 this 和 super 关键字,因为静态方法在使用前不用创建任何实例对象,当静态方法调用时,this 所引用的对象根本没有产生。

静态程序块:当一个类需要在被载入时就执行一段程序或者加载资源,这样可以使用静态程序块。

2.5. ✅✅类加载相关

2.5.1. 静态变量的内存分配和零值赋值

在类加载过程中链接阶段的第二个小阶段,准备阶段,分配内存并赋零值

2.5.1.1. 被 final 修饰的基本数据类型

赋零值是在编译阶段,在准备阶段进行的是显示初始化,就是说此种情况已经在准备阶段初始化完成了,不会在类加载的初始化阶段再进行初始化。也就是说此类变量的使用,不会触发类的初始化动作

2.5.1.2. 被 final 修饰但涉及计算

因为涉及到计算,所以必须在 <clinit> 中进行计算赋值,所以此种类型的变量的使用会触发类的初始化动作

2.5.2. 静态变量初始化

在初始化阶段执行 <clinit> 方法时进行

2.5.3. 静态代码块执行

在初始化阶段执行 <clinit> 方法时进行

3. 实战经验

4. 参考与感谢

https://www.cnblogs.com/dotgua/p/6354151.html?utm_source=itdadao&utm_medium=referral
[[[java]static 关键字的四种用法 - dotgua - 博客园]]