java类运行以及static块的执行顺序

本文详细解析了Java中static关键字的执行时机及顺序,包括static块在类初始化时的执行、static方法加载时的执行以及static与extends结合使用时的执行顺序,并通过示例代码帮助理解。

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

一、java类的static块什么时候执行
如果了解JVM原理,我们可以知道,一个类的运行分为以下步骤:
1、装载;2、链接;3、初始化;4、初始化;5,实例化(创建新的实例)
实际上,static块的执行发生在“初始化”的阶段。初始化阶段,jvm主要完成对静态变量的初始化,静态块执行等工作。
下面我们看看执行static块的几种情况:
1、第一次new A()的过程会打印"";因为这个过程包括了初始化
2、第一次Class.forName("A")的过程会打印"";因为这个过程相当于Class.forName("A",true,this.getClass().getClassLoader());
3、第一次Class.forName("A",false,this.getClass().getClassLoader())的过程则不会打印""。因为false指明了装载类的过程中,不进行初始化。不初始化则不会执行static块。
二、java类中static的执行顺序
方法被定义为static就表示这个方法不需要声明类的实例即可执行;比如main方法。而某个类成员被定义为static的时候,它就几乎完全独立于这个类了。 
根据think   in   java2   还有java参考大全中所述,static方法在类刚刚被加载的时候就执行了。 
因此,可以说,static方法是在对程序进行解释的时候执行。 
比如 
class   UseStatic{ 
        static   int   a   =   3; 
        static   int   b; 


        static   void   meth(int   x) 
        { 
                System.out.println( "x   =   "   +   x); 
                System.out.println( "a   =   "   +   a); 
                System.out.println( "b   =   "   +   b); 
                
        } 
static {
    System.out.println("b = "+b);
    }
        static   { 
                System.out.println( "Static   block   initialized. "); 
                b   =   a*4; 
        } 
        public   static   void   main(String[]   args) 
        { 
                meth(42); 
        } 

一旦UseStatic被装载,所有的static语句被执行。首先,a被设置为3,接着System.out.println("b = "+b);打印出 b=0;注意,可以有多个static代码块,按照顺序执行,同时b被默认初始化为0,接着static块执行(打印一条消息),最后,b初始化为a*4或12。然后调用main(),main()调用meth(),把42传递给x。3 个println()语句引用两个static变量a和b,以及局部变量x。

三、extends 和 static 的执行顺序研究

public class A {
public static final String CONSTANT = "1";
static{
System.out.println("a");
}
public A(){
System.out.println("b");
}
}

public class B extends A{
static{
System.out.println("c");
}
public B(){
System.out.println("d");
}
}


public class Test {

public static void main(String[] args){
System.out.println(A.CONSTANT);
A ab = new B();
ab = new B();
}
}
但是注意执行下边的代码就不会执行static块
System.out.println(A.CONSTANT);
因为这个是类的静态常量,在调用类的静态常量的时候不会导致类被加载(这个是我根据结果推断出来的,网上查了查也没有相关的解释,也许是jvm的规定吧)
1
a
c
b
d
b
d
在ab = new B(); 一句的时候会打印
b
d
这说明在实例化子类的时候,父类同时也会实例化。
<think>首先,用户的问题是:“我想理解Javastatic代码、静态变量和静态方法的执行顺序请问javastatic代码静态变量静态方法执行顺序”。这是一个关于Java中静态元素执行顺序的查询。根据系统级指令:-所有行内数学表达式必须使用$...$格式,但这个问题是关于Java的,没有数学表达式,所以可能不需要。-独立公式必须使用$$...$$格式,但同样,这没有公式。- LaTeX语法正确,但Java代码不需要LaTeX。 -使用中文回答。 -生成相关问题。-回答中引用的段落末尾自然地添加引用标识,例如[^1]。用户可见层指令: -回答结构清晰,帮助用户逐步解决问题。-尽量保证回答真实可靠。-参考站内引用:提供了三个引用,但用户说“上述引用仅供参考,并不是用户真正的需求”,所以我需要基于Java知识回答,而不是直接引用这些内容。参考引用内容: -[^1]讨论了static执行顺序,包括静态变量和静态代码。- [^2]详细解释了static静态变量、方法、代码的作用和初始化顺序。 -[^3]给出了一个例子,说明静态代码、静态变量、成员变量等的执行顺序。 关键点从引用中提取: -static修饰的元素在加载时初始化。-静态变量和静态代码的初始化顺序按照它们在代码中的顺序。 -静态内容优先于非静态内容。-在加载时,静态代码和静态变量初始化,然后才是对象创建时的成员变量和构造方法。用户的问题聚焦在:static代码、静态变量和静态方法的执行顺序。注意,静态方法本身不是初始化的一部分;静态方法在调用时执行,但初始化是关于静态变量和代码的。执行顺序:1.当首次被加载时(例如,第一次访问时),所有static元素初始化。 2.初始化顺序:静态变量和静态代码按照它们在代码中出现的顺序执行。3.静态方法在调用时执行,不涉及初始化顺序;它们只是方法。所以,顺序是:-静态变量初始化(赋值)。-静态代码执行。 它们按声明顺序执行。 例如,在代码中: ```javapublic classExample{static inta =10; //静态变量初始化static {System.out.println("Staticblock1");//静态代码}staticint b=20;static{System.out.println("Static block2");} }``` 加载时,顺序是:- a初始化(10)-第一个静态代码执行- b初始化(20) -第二个静态代码执行静态方法,如publicstatic voidmyMethod(),在调用时执行,比如Example.myMethod(),不参与初始化顺序。 回答结构:1.解释static元素的初始化时机:加载时。2.描述执行顺序:静态变量和静态代码按代码顺序执行。 3.强调静态方法在调用时执行。4.提供简单代码示例。5.生成相关问题。使用中文。生成相关问题: 基于主题,可以问:1.静态元素和非静态元素的执行顺序差异? 2.如何优化静态初始化? 3.静态代码的使用场景?4.在继承中的执行顺序?引用标识:如果引用参考内容,但用户说“请尽可能多的参考用户上一次的问题和你的回答”,但这是第一次交互,所以基于知识回答。如果需要,可以自然添加引用,但引用是站内的,可能不直接相关。 最终回答大纲: -介绍:静态元素在加载时初始化。 -详细顺序:静态变量和静态代码按声明顺序执行。-示例代码。 -静态方法说明。 -相关问题。</think>### Javastatic代码、静态变量和静态方法的执行顺序Java中,`static`修饰的元素(包括静态代码、静态变量和静态方法)在加载阶段初始化,而非对象创建阶段。执行顺序遵循严格的规则,确保静态内容优先初始化。以下是详细解释: #### 1. **初始化时机** - 当首次被加载时(例如,首次访问的静态成员或创建对象),JVM会初始化所有`static`元素。 - 静态内容仅初始化一次,且优先于非静态内容(如成员变量或构造方法)[^2][^3]。 #### 2. **执行顺序规则** - **静态变量和静态代码按声明顺序执行**:在加载时,静态变量赋值和静态代码按照它们在代码中出现的顺序依次执行。 - 例如: ```java public class Example { static int a = initA(); // 静态变量1 static { System.out.println("静态代码1"); // 静态代码1 } static int b = 20; // 静态变量2 static { System.out.println("静态代码2"); // 静态代码2 } private static int initA() { System.out.println("初始化a"); return 10; } } ``` 加载时,顺序为: 1. `a`初始化(调用`initA()`)。 2. 执行第一个静态代码。 3. `b`初始化。 4. 执行第二个静态代码。 - **静态方法不参与初始化顺序**:静态方法(如`public static void myMethod()`)仅在调用时执行,与加载无关。例如,`Example.myMethod()`会在需要时运行,不影响静态变量或代码的初始化[^2]。 #### 3. **关键原则** - **静态优先于非静态**:所有静态元素初始化完成后,才会处理成员变量、构造代码或构造方法。 - **顺序依赖代码位置**:如果静态变量和静态代码交错声明,JVM严格按代码顺序执行。 - **继承中的顺序**:在子加载时,先初始化父的静态内容,再初始化子的静态内容[^3]。 #### 4. **示例验证** 运行以下代码: ```java public class Test { static { System.out.println("静态代码执行"); } static int var = initVar(); private static int initVar() { System.out.println("静态变量初始化"); return 5; } public static void main(String[] args) { System.out.println("main方法执行"); } } ``` 输出: ``` 静态代码执行 静态变量初始化 main方法执行 ``` 说明:静态代码和静态变量按顺序执行,`main`方法(静态方法)在加载后调用。 #### 5. **注意事项** - 静态代码常用于一次性初始化静态变量或资源(如数据库连接)[^2]。 - 静态方法不能直接访问非静态成员,因为非静态内容尚未初始化[^2]。 - 如果多个依赖,加载顺序遵循引用关系,但每个内部的静态顺序不变[^3]。 通过理解这些规则,您可以避免初始化顺序导致的错误,如空指针异常[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值