title: Java类中static{}语句讨论
search: 2024-03-19
tags:
- “#Java类中的Static使用”
Java类中static{}语句解释
一、static{} 基础调用
tips
:static{}
(即static
块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法
示例
Test
类,目录结构 包为 package org.example;
class Test{
public static int X = 100;
public final static int Y = 200;
public Test(){
System.out.println("Test构造函数执行");
}
static{
System.out.println("static语句块执行");
}
public static void display(){
System.out.println("静态方法被执行");
}
public void display_1(){
System.out.println("实例方法被执行");
}
}
package org.example;
public class Main {
public static void main(String[] args) {
try{
Class.forName("org.example.Test"); // 这里面要写类的全名,在多模块项目中
Class.forName("org.example.Test"); // 单模块项目中不需要写全类名
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
}
运行结果:
static语句块执行
可以看到 static
只执行了一次。
类加载四大含义
1
:显示类加载,如Class.forName()
调用
2
:实例化一个类,如Test t = new Test();
实例
3
:调用类静态方法,如Test.display();
4
:调用类静态变量,如System.out.println(Test.X)
注意以下两点
一、调用类静态常量时,是不会加载类的,即不会执行 static{}
语句块,(Java
虚拟机规定,当访问类的静态常量时,如果编译器可以计算出常量的值,则不会加载类,否则会加载类)
二、用Class.forName()
形式的时候,我们可以设定不要加载类,变为 Class.forName("org.example.Test",false,StaticBlockTest.class.getClassLoader())
二、static{} 执行顺序
一、当一个类中有多个static{}
的时候,按照static{}
的定义顺序,从前往后执行;
二、先执行完static{}
语句块内容,才会执行调用语句;
public class TestStatic{
public static void main(String args[]){
System.out.println(5);
}
static{
System.out.println(1);
}
static {
System.out.println(2);
}
static {
System.out.println(3);
}
static {
System.out.println(4);
}
}
运行结果:
1,2,3,4,5
三、当一个类中既有static{}
又有 static
变量的时候,同样遵循 先定义先执行
的原则
class Test{
public static int X=300;
static{
System.out.println(X);
X=200;
System.out.println(X);
}
}
public class StaticBlockTest{
public static void main(String args[]){
System.out.println(Test.X);
}
}
运行结果:
300
200
200
三、static 应用场景
1、静态变量
-
当成员变量声明为
static
时,它属于类级别,而非对象级别。也就是说,无论创建多少个对象,所有对象共享同一份静态变量副本,且在类加载时初始化,生命周期贯穿整个应用程序。 -
示例:
1public class MyClass { 2 public static int count = 0; 3 // ... 4}
在上面的例子中,每次创建
MyClass
的对象时,count
不会重新初始化,而是所有对象共用同一个count
变量。
2、静态方法
-
静态方法也是属于类级别的,不需要通过对象实例就可以调用,不能访问非静态成员变量和方法(除非它们是通过传递的对象引用访问的)。
-
静态方法常用于工具类或者不需要涉及对象状态的操作,如数学计算、IO操作等。
-
示例:
1public class MathUtils { 2 public static int add(int a, int b) { 3 return a + b; 4 } 5 // ... 6}
上述
MathUtils
类中的add
方法可以直接通过类名调用,如MathUtils.add(1, 2)
。
3、静态
-
静态块在类加载时执行,且只执行一次,主要用于初始化静态变量。
-
示例:
1public class MySingleton { 2 private static MySingleton instance; 3 static { 4 instance = new MySingleton(); 5 } 6 // ... 7}
在上面的单例模式实现中,静态块用于初始化单例对象。
4、静态内部类
-
静态内部类不需要持有外部类的引用,它可以独立于外部类实例而存在,通常用于组织相关功能,降低耦合度。
-
示例:
1public class OuterClass { 2 public static class InnerClass { 3 // ... 4 } 5}
在上面的例子中,
InnerClass
可以直接通过OuterClass.InnerClass
的形式创建实例,而不必依赖于OuterClass
的实例。