`
Yinny
  • 浏览: 296379 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

Java 类中类属性 (static 变量) 和对象属性 (非 static 变量) 的初始化顺序

阅读更多



Java 类中类属性 (static 变量) 和对象属性 (非 static 变量) 的初始化顺序可以用如下程序测试:

/**

* @(#) Test.java
* @author fancy
*/

public class Test {

static String a = "string-a";
static String b;

String c = "stirng-c";
String d;

static {
printStatic("before static");
b = "string-b";
printStatic("after static");
}

public static void printStatic(String title) {
System.out.println("---------" + title + "---------");
System.out.println("a = \"" + a + "\"");
System.out.println("b = \"" + b + "\"");
}

public Test() {
print("before constructor");
d = "string-d";
print("after constructor");
}

public void print(String title) {
System.out.println("---------" + title + "---------");
System.out.println("a = \"" + a + "\"");
System.out.println("b = \"" + b + "\"");
System.out.println("c = \"" + c + "\"");
System.out.println("d = \"" + d + "\"");
}

public static void main(String[] args) {
new Test();
}

}

首先,我把 main() 方法注释掉,运行结果如下:

---------before static---------
a = "string-a"
b = "null"
---------after static---------
a = "string-a"
b = "string-b"
java.lang.NoSuchMethodError: main
Exception in thread "main"
Process completed.

然后,取消对 main() 方法的注释,运行结果如下:

---------before static---------
a = "string-a"
b = "null"
---------after static---------
a = "string-a"
b = "string-b"
---------before constructor---------
a = "string-a"
b = "string-b"
c = "stirng-c"
d = "null"
---------after constructor---------
a = "string-a"
b = "string-b"
c = "stirng-c"
d = "string-d"

由此可以看出 Java 类属性和对象属性的初始化顺序如下:

① 类属性 (静态变量) 定义时的初始化,如上例的 static String a = "string-a";
② static 块中的初始化代码,如上例 static {} 中的 b = "string-b";
③ 对象属性 (非静态变量) 定义时的初始化,如上例的 String c = "stirng-c";
④ 构造方法 (函数) 中的初始化代码,如上例构造方法中的 d = "string-d";


在此过程中 ② 和 ③ 的顺序无所确定,因为在静态块中无法打印出非静态变量。同样是因为这个原因,知道他们的顺序对我们写程序也毫无帮助。再因为类成员 (静态成员) 是在第一次使用到类的时候就进行了相应的初始化,而对象成员 (非静态成员) 则需要生成类实例 (即对象) 时才能初始化,所以我把 ③ 排在了 ② 的后面。再申明一次,它们究竟谁先谁后,从代码上是不能确定的,恐怕需要去研究一下 JVM (Java 虚拟机) 的执行过程才行。
分享到:
评论

相关推荐

    探究java的ClassLoader及类变量初始化顺序

    同时,掌握类变量初始化顺序可以避免因误解而导致的错误,特别是在多线程环境中,对静态变量的并发访问和初始化顺序的控制需要特别注意。 总之,深入理解Java的ClassLoader机制和类变量初始化顺序是提升Java编程...

    java中的static变量,方法,代码块

    Static变量 `static`变量,亦称为静态变量或类变量,与实例变量相对。其最显著的特点在于,无论创建多少个该类的实例,`static`变量在内存中仅存在一份拷贝,这意味着所有实例共享同一份变量值。这不仅节约了内存...

    C++全局变量初始化的一点总结

    C++中的全局变量初始化是一个重要的话题,涉及到程序的正确性和可预测性。全局变量,即具有静态存储期的变量,其生命周期始于程序开始,终于程序结束。本文将深入探讨全局变量初始化的时机、方式以及一些处理特殊...

    Java静态初始化块和对象初始化块

    总之,理解并有效地使用静态和对象初始化块是Java开发中的关键技能,它们可以帮助我们更好地控制类和对象的初始化过程,确保代码的高效性和正确性。在实际编程中,我们应该根据需求谨慎选择合适的初始化策略,以优化...

    java面试题-类的初始化顺序.doc

    这个顺序表明,无论类之间的继承关系如何,初始化顺序始终是:静态变量和静态初始化块先于非静态成员。在创建对象时,父类的初始化先于子类。这是Java语言规范所规定的,确保在子类访问父类的静态或非静态成员时,...

    java中类的初始化顺序

    ### Java中类的初始化顺序详解 #### 一、概述 在Java编程语言中,类的初始化是一个非常重要的概念。类的初始化涉及到多个方面,包括静态成员变量、实例成员变量、静态初始化块、实例初始化块以及构造函数等。本文...

    Java初始化顺序1

    在上面的示例代码中,我们可以看到,类变量和实例变量的初始化顺序是按照定义的顺序进行的。同时,我们还可以看到,静态变量的初始化顺序是按照定义的顺序,并且只在第一次访问时初始化。 在 Java 中,static ...

    类继承的初始化顺序类,继承的初始化顺序

    4. **子类非静态成员初始化**:接着是子类的非静态成员变量初始化。 5. **基类构造函数调用**:通过`super()`调用基类的构造函数。 6. **子类构造函数调用**:最后执行子类自身的构造函数。 ### 初始化过程详解 ##...

    java程序初始化顺序

    在Java编程语言中,程序初始化的顺序是一个关键概念,它涉及到类加载、对象创建以及执行流程的安排。了解这些顺序对于编写高效、无错误的代码至关重要。以下是对Java程序初始化顺序的详细说明: 1. **类加载阶段**...

    Java中static静态变量的初始化完全解析

    Java中的静态变量(static变量)是在类加载时初始化的,而不是在对象创建时。静态变量属于类,而不属于任何特定的对象,因此它们是共享的,所有类实例都可以访问。了解静态变量的初始化顺序对于理解和避免潜在的编程...

    类的static,const,static const,const static成员的初始化

    因此,static 成员变量不能在定义对象时对变量初始化,用构造函数来初始化。其正确的初始化方式是: ```cpp class Foo { private: static int i; }; int Foo::i = 100; // 在类体外初始化 ``` 这表明: * 初始化...

    Static和Final修饰类属性变量及初始化

    1.static修饰一个属性字段,那么这个属性字段将成为类本身的资源,public修饰为共有的,可以在类的外部通过test.a来访问此属性;在类内部任何地方可以使用.如果被修饰为private私有,那么只能在类内部使用.

    java类中静态域、块,非静态域、块,构造函数的初始化顺序

    ### Java 类中静态域、块,非静态域、块,构造函数的初始化顺序 #### 一、概述 在 Java 编程语言中,类的初始化顺序对于理解程序的行为至关重要。特别是当涉及到静态域(静态变量)、非静态域(实例变量)、静态块...

    Java static修饰成员变量

    Java中的`static`关键字是编程中的一个重要概念,它在Java语言中扮演着多个角色,尤其在处理类和对象时起到关键作用。`static`关键字可以用来修饰成员变量、方法、代码块以及内部类,每种情况都有其特定的含义和用途...

    Java static静态初始快

    `static`在Java中用于声明类变量或静态方法,这些变量和方法不需要创建对象就能被访问。它们是与类关联的,而不是与类的任何特定实例关联。这意味着无论创建了多少个类的实例,静态变量只有一份拷贝,所有实例共享这...

    JAVA面试题解惑系列(一)——类的初始化顺序-JAVA程序员JAVA工程师面试必看.pdf,这是一份不错的文件

    ANSWER: 静态变量和静态初始化块的初始化顺序是最高的,因此 Father 类中的静态变量和静态初始化块将首先被初始化,接着是 Son 类中的静态变量和静态初始化块。然后是变量和初始化块,最后是构造器。 以下是一个...

    java中如何使用Static的变量和方法.doc

    在Java中,`static`关键字用于声明类的成员变量(静态变量)和成员方法(静态方法),这些成员不依赖于类的任何特定实例,因此可以在没有创建类的实例的情况下进行访问。 #### Static变量的特点 1. **共享性**:当...

    Java中的static关键字

    Java 中的 static 关键字 ...在 Java 中,类装载器把一个类装入 Java 虚拟机中,要经过三个步骤来完成:装载、链接和初始化,其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的。

    java中static属性学习

    本文详细介绍了Java中的`static`属性,包括静态成员变量、静态方法以及静态语句块的概念和使用方法。通过具体的代码示例,我们不仅了解了`static`关键字的基本用法,还深入探讨了静态成员变量如何在整个类之间共享,...

    static静态变量使用@Value注入方式.md

    静态变量在类加载时就已经初始化完毕,而Spring Bean的初始化通常发生在应用程序启动过程中,两者的时间点不同步。因此,直接在静态变量上使用`@Value`会导致注入失败,并且在编译或运行时出现警告或错误信息。 ###...

Global site tag (gtag.js) - Google Analytics