java:对象初始化顺序

为了演示,我们把实例属性、静态属性、实例方法、静态方法、构造方法、代码块、静态代码块都加上 

package com.qzcsbj;

/**
 * @create : 2020/3/22 14:29
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class User {
    String name = "全栈测试笔记";  // 实例属性
    static String job = "tester";  // 静态属性

    public void a(){
        System.out.println("实例方法。");
    }

    public static void b(){
        System.out.println("静态方法。");
    }

    public User(){
        System.out.println("构造方法。");
    }

    {
        System.out.println("代码块。");
    }

    static{
        System.out.println("静态代码块。");
    }
}

  

创建对象

package com.qzcsbj;

/**
 * @create : 2020/3/22 14:43
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class Test {
    public static void main(String[] args) {
        User user = new User();
    }
}

  

结果:代码块在构造方法后面定义,但是先执行

静态代码块。
代码块。
构造方法。

  

调用静态方法

package com.qzcsbj;

/**
 * @create : 2020/3/22 14:43
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class Test {
    public static void main(String[] args) {
        // User user = new User();
        User.b();
    }
}

  

结果:下面说明,只要加载类,就会执行静态代码块,和是否创建类无关

静态代码块。
静态方法。

  

加载指定的类

package com.qzcsbj;

/**
 * @create : 2020/3/22 14:43
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        // User user = new User();
        // User.b();
        Class.forName("com.qzcsbj.User");
    }
}

结果:加载类,就会执行静态代码块

静态代码块。

  

在静态代码块里面初始化静态变量

    static{
        System.out.println("静态代码块。");
        job = "QA";
    }

  

package com.qzcsbj;

/**
 * @create : 2020/3/22 14:43
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        // User user = new User();
        // User.b();
        Class.forName("com.qzcsbj.User");
        System.out.println(User.job);
    }
}

  

结果:指定加载类后,访问属性,结果说明,类加载,静态属性也初始化了

静态代码块。
QA

创建多个对象

package com.qzcsbj;

/**
 * @create : 2020/3/22 14:43
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        User user = new User();
        User user2 = new User();
        // User.b();
        // Class.forName("com.qzcsbj.User");
        // System.out.println(User.job);
    }
}
package com.qzcsbj;

/**
 * @create : 2020/3/22 14:29
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class User {
    String name = "全栈测试笔记";  // 实例属性
    static String job = "tester";  // 静态属性

    public void a(){
        System.out.println("实例方法。");
    }

    public static void b(){
        System.out.println("静态方法。");
    }

    public User(){
        System.out.println("构造方法。");
    }

    {
        System.out.println("代码块。");
    }

    static{
        System.out.println("静态代码块。");
        job = "QA";
    }
}

  

结果:下面说明,静态代码块只执行一次,静态代码块是在加载类时候执行的,说明类只加载一次

静态代码块。
代码块。
构造方法。
代码块。
构造方法。

  

调整静态代码块和静态属性顺序

package com.qzcsbj;

/**
 * @create : 2020/3/22 14:29
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class User {
    static{
        System.out.println("静态代码块。");
        job = "QA";
    }
    
    String name = "全栈测试笔记";  // 实例属性
    static String job = "tester";  // 静态属性

    public void a(){
        System.out.println("实例方法。");
    }

    public static void b(){
        System.out.println("静态方法。");
    }

    public User(){
        System.out.println("构造方法。");
    }

    {
        System.out.println("代码块。");
    }

}

  

package com.qzcsbj;

/**
 * @create : 2020/3/22 14:43
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        // User user = new User();
        // User user2 = new User();
        // User.b();
        Class.forName("com.qzcsbj.User");
        System.out.println(User.job);
    }
}

  

结果:说明执行静态属性和静态代码块,是根据定义的顺序,从上往下执行

静态代码块。
tester

  

代码块中堆实例属性初始化

package com.qzcsbj;

/**
 * @create : 2020/3/22 14:29
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class User {
    static{
        System.out.println("静态代码块。");
        job = "QA";
    }

    String name = "全栈测试笔记";  // 实例属性
    static String job = "tester";  // 静态属性

    public void a(){
        System.out.println("实例方法。");
    }

    public static void b(){
        System.out.println("静态方法。");
    }

    public User(){
        System.out.println("构造方法。");
    }

    {
        System.out.println("代码块。");
        name = "qzcsbj";
    }
}

  

package com.qzcsbj;

/**
 * @create : 2020/3/22 14:43
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        User user = new User();
        System.out.println(user.name);
        // User user2 = new User();
        // User.b();
        // Class.forName("com.qzcsbj.User");
        // System.out.println(User.job);
    }
}

  

结果:说明先执行了实例属性初始化,再执行代码块中赋值

静态代码块。
代码块。
构造方法。
qzcsbj

  

调整静态代码块和静态属性

package com.qzcsbj;

/**
 * @create : 2020/3/22 14:43
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        User user = new User();
        System.out.println(user.name);
        // User user2 = new User();
        // User.b();
        // Class.forName("com.qzcsbj.User");
        // System.out.println(User.job);
    }
}
package com.qzcsbj;

/**
 * @create : 2020/3/22 14:29
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class User {
    static{
        System.out.println("静态代码块。");
        job = "QA";
    }

    {
        System.out.println("代码块。");
        name = "qzcsbj";
    }

    String name = "全栈测试笔记";  // 实例属性
    static String job = "tester";  // 静态属性

    public void a(){
        System.out.println("实例方法。");
    }

    public static void b(){
        System.out.println("静态方法。");
    }

    public User(){
        System.out.println("构造方法。");
    }

}

  

结果:执行实例属性和代码块,是根据定义的顺序,从上往下执行

静态代码块。
代码块。
构造方法。
全栈测试笔记

构造方法中初始化

package com.qzcsbj;

/**
 * @create : 2020/3/22 14:29
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class User {

    String name = "全栈测试笔记";  // 实例属性
    static String job = "tester";  // 静态属性

    public void a(){
        System.out.println("实例方法。");
    }

    public static void b(){
        System.out.println("静态方法。");
    }

    public User(){
        System.out.println("构造方法。");
        this.name = "性能测试";
    }

    static{
        System.out.println("静态代码块。");
        // job = "QA";
    }

    {
        System.out.println("代码块。");
        name = "qzcsbj";
    }

}

  

package com.qzcsbj;

/**
 * @create : 2020/3/22 14:43
 * @description : <描述>
 * @博客 : www.cnblogs.com/uncleyong
 * @QQ群 : 652122175
 * @公众号 : 全栈测试笔记
 */
public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        User user = new User();
        System.out.println(user.name);
        // User user2 = new User();
        // User.b();
        // Class.forName("com.qzcsbj.User");
        // System.out.println(User.job);
    }
}

  

结果:

静态代码块。
代码块。
构造方法。
性能测试

总结

执行先后顺序: 静态代码块 → 代码块 → 构造方法

注意:不要在构造器中对静态成员进行初始化。

原文地址:https://www.cnblogs.com/uncleyong/p/12545986.html