java static块的执行次数

本文深入解析静态块在类实例化过程中的原子执行机制及其在多线程环境下的表现,通过代码示例展示了静态块如何确保在多线程并发时的顺序执行,并解释了其原理及应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

比较有意思的一段代码,可以先运行看效果再将注释取消后看运行效果,上代码

/**
 * 
 * 每个对象实例化的时候,都要路过static方法
 * 但是编译器会保证static快的执行是原子的,即便是多线程过来也要一个个执行
 * 只不过,只有第一个实例动作的时候static快内的代码被执行
 * 其他实例只是“路过”
 * 即,每个实例都要走到static块,但是static块只会执行一次,
 * 是通过调用该类的 client方法导致的,该方法只在类被加载的时候JVM调用
 * @author liuinsect
 *
 */
public class StaticBlockTest  implements Runnable{
	
	static{
		if(true){
			System.out.println("test");
//			while(true){
//				
//			}
		}
		
	}
	
	@Override
	public void run() {
		
		System.out.println("run");
	}
	
	/**
	 * @author liuinsect 	
	 * @date 2013-2-7
	 * @param args
	 */
	public static void main(String[] args) {
		StaticBlockTest s = new StaticBlockTest();
		StaticBlockTest s1 = new StaticBlockTest();
//		StaticBlockTest s2 = new StaticBlockTest();
//		StaticBlockTest s3 = new StaticBlockTest();
//		StaticBlockTest s4 = new StaticBlockTest();
//		StaticBlockTest s5 = new StaticBlockTest();
		Thread t1 = new Thread(s);
		Thread t2 = new Thread(s1);
		
		
		t1.start();
		t2.start();
		
	}



}

 

<think>好的,我现在需要帮助用户了解Java中的static语句,也就是静态代码。首先,用户之前询问过关于通过对象实例调用静态属性的问题,现在他们可能想更深入地了解static的其他用法,特别是静态代码。 我应该先回顾用户的历史问题,确保这次回答连贯。用户之前的问题涉及到静态属性和不推荐的调用方式,所以现在需要扩展static的其他方面。用户提到“static语句static”,可能是指静态代码static block),或者可能打字重复了,但根据常见问题,静态代码是合理的解释。 接下来,我需要明确静态代码的定义和用途。静态代码static关键字修饰,并在类加载时执行,通常用于初始化静态变量或执行一次性操作。需要强调它只执行一次,不管创建多少对象实例。 然后,考虑用户可能的疑惑点。比如,静态代码与构造方法的区别,执行顺序,以及多个静态执行顺序。这些都是常见的问题点,应该在回答中涵盖。 用户可能想知道何时使用静态代码,所以需要举一些实际例子,比如加载配置文件、初始化静态资源等。同时,要提到注意事项,比如无法访问实例成员,只能处理静态内容。 还要注意用户可能对语法有疑问,所以给出示例代码是必要的。需要确保代码正确,并解释关键点,比如类加载时执行,只执行一次,多个静态执行顺序按定义顺序。 最后,总结静态代码的优缺点,以及适用场景,帮助用户全面理解。同时,关联之前的回答,强调通过类名访问静态成员的正确做法,保持一致性。 需要避免使用专业术语过多,用简单的中文解释,结构清晰,分点说明,方便用户理解。检查是否有遗漏的重要信息,比如错误处理,或者静态代码中的异常处理,但可能用户现阶段不需要太深入,保持回答简洁即可。</think>以下是关于 Java 中 **静态代码static block)** 的详细介绍: --- ### 一、静态代码的定义 - **语法形式**:用 `static { ... }` 包裹的代码 - **核心特性**: - 在**类加载时自动执行**(早于对象创建) - 仅执行**一次**(无论创建多少对象实例) - 主要用于**初始化静态变量**或执行**一次性类级操作** ```java public class MyClass { static int staticVar; // 静态代码 static { staticVar = initializeStaticVar(); System.out.println("静态代码执行"); } private static int initializeStaticVar() { return 100; } } ``` --- ### 二、静态代码的作用 #### 1. **复杂静态成员初始化** 当静态变量的初始化需要多步逻辑时(例如读取文件、计算值): ```java static List<String> configList; static { configList = new ArrayList<>(); // 从文件加载配置 try { Files.lines(Paths.get("config.txt")).forEach(configList::add); } catch (IOException e) { e.printStackTrace(); } } ``` #### 2. **类加载时的预操作** 例如注册驱动、建立数据库连接池: ```java static Connection connection; static { try { Class.forName("com.mysql.cj.jdbc.Driver"); connection = DriverManager.getConnection(url, user, password); } catch (Exception e) { throw new RuntimeException("数据库连接失败", e); } } ``` #### 3. **保证初始化顺序** 多个静态代码按定义顺序执行: ```java static int a; static { a = 10; // 先执行 } static int b; static { b = a * 2; // 后执行,此时a已初始化 } ``` --- ### 三、关键特性与注意事项 #### 1. **执行时机对比** | **代码类型** | 执行时机 | 执行次数 | |--------------------|----------------------------|-----------| | 静态代码 | 类加载时(首次使用类前) | 1次 | | 实例代码 | 每次创建对象时 | N次(与对象数相同) | | 构造方法 | 每次创建对象时 | N次 | #### 2. **重要规则** - **无法访问实例成员**:静态代码中不能直接使用非静态变量或方法 - **异常处理**:若静态代码抛出未捕获的异常,类将无法加载 - **继承关系**:父类的静态代码优先于子类执行 --- ### 四、典型应用场景 1. **加载配置文件**(如数据库连接参数) 2. **初始化静态容器**(如缓存静态数据到集合) 3. **注册驱动或服务**(如JDBC驱动) 4. **执行类级验证逻辑**(如检查依赖环境) --- ### 五、代码示例分析 ```java public class Demo { static int x; static { x = 10; System.out.println("静态代码1: x = " + x); } static { x += 5; System.out.println("静态代码2: x = " + x); } public static void main(String[] args) { // 首次触发类加载 new Demo(); // 第二次创建对象,静态代码不会再次执行 new Demo(); } } ``` **输出结果**: ``` 静态代码1: x = 10 静态代码2: x = 15 ``` --- ### 六、总结对比 | **特性** | 静态代码 | 实例代码 | |------------------|--------------------------------|-----------------------| | 关键字 | `static {}` | `{}` | | 执行时机 | 类加载时 | 对象构造时 | | 访问权限 | 仅限静态成员 | 可访问静态+实例成员 | | 异常处理 | 必须捕获或声明为Error | 可抛出给构造函数处理 | | 典型用途 | 静态资源初始化 | 对象公共初始化逻辑 | --- **最佳实践**: - 优先用静态代码处理**类级别的初始化** - 避免在静态代码中编写复杂业务逻辑 - 如需处理异常,建议包装成 `Error` 或终止程序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值