浅谈Java变量的初始化顺序详解_java

规则1(无继承情况下):
对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是
(静态变量、静态初始化块)>(变量、初始化块)>构造器
证明代码:

复制代码 代码如下:

public class InitialOrderTest {
    // 静态变量
    public static String staticField = "静态变量";
    // 变量
    public String field = "变量";
    // 静态初始化块
    static {
        System.out.println(staticField);
        System.out.println("静态初始化块");
    }
    // 初始化块
    {
        System.out.println(field);
        System.out.println("初始化块");
    }
    // 构造器
    public InitialOrderTest() {
        System.out.println("构造器");
    }
    public static void main(String[] args) {
        new InitialOrderTest();
    }
}

结果显示:
静态变量
静态初始化块
变量
初始化块
构造器

规则2(有继承情况下):
子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成

复制代码 代码如下:

class Parent {
    // 静态变量
    public static String p_StaticField = "父类--静态变量";
    // 变量
    public String p_Field = "父类--变量";
    // 静态初始化块
    static {
        System.out.println(p_StaticField);
        System.out.println("父类--静态初始化块");
    }
    // 初始化块
    {
        System.out.println(p_Field);
        System.out.println("父类--初始化块");
    }
    // 构造器
    public Parent() {
        System.out.println("父类--构造器");
    }
}//如果你想把这两个类放在同一个文件且名字起为SubClass, 父类前不能加public
public class SubClass extends Parent { 
    // 静态变量
    public static String s_StaticField = "子类--静态变量";
    // 变量
    public String s_Field = "子类--变量";
    // 静态初始化块
    static {
        System.out.println(s_StaticField);
        System.out.println("子类--静态初始化块");
    }
    // 初始化块
    {
        System.out.println(s_Field);
        System.out.println("子类--初始化块");
    }
    // 构造器
    public SubClass() {
        System.out.println("子类--构造器");
    }
    // 程序入口
    public static void main(String[] args) {
        new SubClass();
    }
}

结果显示:
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器

规则2(静态变量和静态初始化块):
静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。同样,变量和初
始化块也遵循这个规律。

复制代码 代码如下:

public class testOrder {
    // 静态变量
    public static TestA a = new TestA();
    public TestC c = new TestC();
    // 静态变量
    public static TestB b = new TestB();
    public testOrder(){
        System.out.println("in constract");
    }
    // 静态初始化块
    static {
        System.out.println("静态初始化块");
    }
    public static void main(String[] args) {
        new testOrder();
    }
}
class TestA {
    public TestA() {
        System.out.println("Test--A");
    }
}
class TestB {
    public TestB() {
        System.out.println("Test--B");
    }
}
class TestC {
    public TestC() {
        System.out.println("Test--C");
    }
}

结果显示:
Test--A
Test--B
静态初始化块
Test--C
in constract

个人总结:
先静后动,先父后子,从上到下,先变量后构造

时间: 2024-08-07 17:49:35

浅谈Java变量的初始化顺序详解_java的相关文章

java类中元素初始化顺序详解_java

复制代码 代码如下: public class Test4 {    @Test    public void test(){        child child = new child();    }} class parent{    public static String parentStaticField = "父类静态变量";    public String parentNormalField ="父类普通变量";    static {      

浅谈AngularJs指令之scope属性详解_AngularJS

AngularJS使用directive()方法类定义一个指令: .directive("name",function(){ return{ }; }) 上面是定义一个指令的主体框架,该方法接受两个参数: 1.第一个参数:name表示定义的指令的名称(angularjs会用这个name注册这个指令) 2.第二个参数:函数,该番薯必须返回一个对象或者一个函数,但通常我们会返回一个对象.return后接的就是返回的对象. 在返回的对象中有一个scope属性,这个属性用来修饰指令的作用域.

浅谈java泛型的作用及其基本概念_java

一.泛型的基本概念 java与c#一样,都存在泛型的概念,及类型的参数化.java中的泛型是在jdk5.0后出现的,但是java中的泛型与C#中的泛型是有本质区别的,首先从集合类型上来说,java 中的ArrayList<Integer>和ArrayList<String>是同一个类型,在编译时会执行类型擦除,及java中的类型是伪泛型,伪泛型将会在后面介绍,其次,对于像集合中添加基本类型的数据时,例如int,会首先将int转化成Integer对象,即我们通常所说的装箱操作,在取出

浅谈Java的String中的subString()方法_java

方法如下: public String substring(int beginIndex, int endIndex) 第一个int为开始的索引,对应String数字中的开始位置, 第二个是截止的索引位置,对应String中的结束位置 1.取得的字符串长度为:endIndex - beginIndex; 2.从beginIndex开始取,到endIndex结束,从0开始数,其中不包括endIndex位置的字符 如: "hamburger".substring(4, 8) returns

基于Java中字符串内存位置详解_java

前言 之前写过一篇关于JVM内存区域划分的文章,但是昨天接到蚂蚁金服的面试,问到JVM相关的内容,解释一下JVM的内存区域划分,这部分答得还不错,但是后来又问了Java里面String存放的位置,之前只记得String是一个不变的量,应该是要存放在常量池里面的,但是后来问到new一个String出来应该是放到哪里的,这个应该是放到堆里面的,后来又问到String的引用是放在什么地方的,当时傻逼的说也是放在堆里面的,现在总结一下:基本类型的变量数据和对象的引用都是放在栈里面的,对象本身放在堆里面,

Java中Properties的使用详解_java

Java中有个比较重要的类Properties(Java.util.Properties),主要用于读取Java的配置文件,各种语言都有自己所支 持的配置文件,配置文件中很多变量是经常改变的,这样做也是为了方便用户,让用户能够脱离程序本身去修改相关的变量设置.今天,我们就开始Properties的使用. Java中Properties的使用 Properties的文档说明: The Properties class represents a persistent set of propertie

Java静态方法不具有多态性详解_java

动态绑定机制使得基类的引用能够指向正确的子类对象,从而使得面向基类编程成为可能. 然而动态绑定在以下两种情况会失效. 1.基类方法是private或final修饰的 这个很好理解,因为private说明该方法对子类是不可见的,子类再写一个同名的方法并不是对父类方法进行复写(Override),而是重新生成一个新的方法,也就不存在多态的问题了.同理也可以解释final,因为方法同样是不可覆盖的. 2.方法是static修饰的 代码如下所示. class Base { public static v

浅谈Java中父类与子类的加载顺序详解_java

复制代码 代码如下: class Parent {    // 静态变量    public static String p_StaticField = "父类--静态变量";    // 变量(其实这用对象更好能体同这一点,如专门写一个类的实例)     //如果这个变量放在初始化块的后面,是会报错的,因为你根本没有被初始化    public String p_Field = "父类--变量";    // 静态初始化块    static {        S

Java 23种设计模型详解_java

设计模式(Design Patterns)                                   --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样.项目中合理的运用设计模式可以完美的解决很多问题,每