首页 > 试题广场 >

有关构造函数说法正确的是?

[不定项选择题]
有关静态初始化块说法正确的是?
  • 无法直接调用静态初始化块
  • 在创建第一个实例前或引用任何静态成员之前,将自动调用静态初始化块来初始化
  • 静态初始化块既没有访问修饰符,也没有参数
  • 在程序中,用户可以控制何时执行静态初始化块

java对象初始化顺序
先说结论:

  1. 父类静态代码块,父类静态成员变量(同级,按代码顺序执行)
  2. 子类静态代码块,子类静态成员变量(同级,按代码顺序执行)
  3. 父类普通代码块,父类普通成员变量(同级,按代码顺序执行)
  4. 父类构造方法
  5. 子类普通代码块,子类普通成员变量(同级,按代码顺序执行)
  6. 子类构造方法

注意点:

  1. 静态内容只在类加载时执行一次,之后不再执行。
  2. 默认调用父类的无参构造方法,可以在子类构造方法中利用super指定调用父类的哪个构造方法。

代码测试:

/**
 * Description: Java对象初始化顺序
 * Created by yangyz on 2018/12/25
 */
class Father {
    public Father() {
        System.out.println("父类无参构造方法");
    }
    static {
        System.out.println("父类静态代码块1");
    }
    private static int a = Help.fatherStaticMemberVarInit();
    static {
        System.out.println("父类静态代码块2");
    }
    {
        System.out.println("父类普通代码块1");
    }
    private int b = Help.fatherMemberVarInit();
    {
        System.out.println("父类普通代码块2");
    }
    public Father(int v) {
        System.out.println("父类带参构造方法");
    }
}

class Son extends Father {
    static {
        System.out.println("子类静态代码块1");
    }
    private static int a = Help.sonStaticMemberVarInit();
    static {
        System.out.println("子类静态代码块2");
    }
    {
        System.out.println("子类普通代码块1");
    }
    private int b = Help.sonMemberVarInit();
    {
        System.out.println("子类普通代码块2");
    }
    public Son() {
        // super(2018);
        System.out.println("子类构造方法");
    }
}

class Help {
    public static int fatherStaticMemberVarInit() {
        System.out.println("父类静态成员变量");
        return 0;
    }
    public static int fatherMemberVarInit() {
        System.out.println("父类普通成员变量");
        return 0;
    }
    public static int sonStaticMemberVarInit() {
        System.out.println("子类静态成员变量");
        return 0;
    }
    public static int sonMemberVarInit() {
        System.out.println("子类普通成员变量");
        return 0;
    }
}

public class Test {
    public static void main(String[] args) {
        Son son1 = new Son();
        System.out.println("===================");
        Son son2 = new Son();
    }
}

测试结果:
图片说明

编辑于 2018-12-25 16:23:15 回复(27)

JAVA的初始化顺序:

父类的静态成员初始化>父类的静态代码块>子类的静态成员初始化>子类的静态代码块>父类的代码块>父类的构造方法>子类的代码块>子类的构造方法

注意:

1.静态成员和静态代码块只有在类加载的时候执行一次,再次创建实例时,不再执行,因为只在方法区存在一份,属于一整个类。

2.上述的是通用的加载顺序,如果没有则省略。




发表于 2017-10-26 18:50:50 回复(13)
这题看的我一脸懵逼,所以干脆没选。
发表于 2017-08-20 15:25:37 回复(8)
题目改正了,静态初始化块。
1. 静态初始化块在类加载时完成,无法人为调用,A对。
2. 关于初始化顺序,参考 江展松 的回答:
父类的静态成员初始化 > 父类的静态代码块 > 子类的静态成员初始化 > 子类的静态代码块 > 父类的代码块 > 父类的构造方法 > 子类的代码块 > 子类的构造方法。且静态成员初始化和静态代码块只有在类加载的时候执行一次,再次创建实例对象时,不再执行,因为只在方法区存在一份,属于整个类共享。因此 B 对。
3. 静态初始化块的标准写法,没有访问修饰符、参数:
static {
    // 初始化内容
}
4. 如果有多个静态块,分别写在代码的不同位置,算不算控制了执行时间?
发表于 2018-02-24 13:04:10 回复(2)
java 没有静态构造函数,只有静态初始化块!!!这道题说法不专业,看题目答案推断,静态构造函数指的是静态初始化块
发表于 2017-08-16 10:07:49 回复(4)
最高赞有问题。正确的是:

JAVA的初始化顺序:
父类的静态区>子类的静态区>父类的代码块>父类的构造方法>子类的代码块>子类的构造方法
静态区包含静态方法和静态代码块,谁在前先执行谁!
发表于 2019-07-06 20:21:02 回复(0)
我觉得这题答案是AC,但是显示ABC,B应该是错的,”引用任何静态成员之前,将自动调用静态初始化块来初始化”这句话就错了,静态成员和静态初始化块是按照声明顺序来执行,谁先在前就先执行谁。
发表于 2021-08-18 16:20:52 回复(2)
静态构造函数(针对类)只执行一次,并且是在第一个实例对象创建前被调用,所以它可以用于那些只需要执行一次的操作;而且它不允许有public等修饰符,由程序自动调用,不能被外界调用
发表于 2017-08-18 12:45:42 回复(0)
B选项错了吧,外界引用静态常量是不会调用静态初始化块初始化的
class Person {     public static final String s = "123";     static {         System.out.println("test...");     }
}

public class Test{     public static void main(String[] args) {         System.out.println(Person.s);
                //输出123     }
}

发表于 2019-03-17 14:31:05 回复(6)
***题,什么叫静态构造函数?WTF?果断屏蔽
编辑于 2017-08-19 10:19:17 回复(0)
不一定吧,因为静态域中静态成员和静态块是按序加载,所以引用静态成员不一定先初始化静态块
发表于 2020-02-21 17:30:57 回复(0)

参考深入理解JVM虚拟机第三版代码清单7-3,
本题答案有误。代码贴不出来。
原话:常量(static final)在编译阶段 会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化。

发表于 2022-02-28 21:17:41 回复(1)
Java的初始化顺序 父类静态成员变量/父类静态代码快>子类静态成员变量/子类静态代码块>父类成员变量>父类普通代码块>子类成员变量>子类普通代码块>父类构造>子类构造 (在同一类中,静态成员变量和静态代码块同级,谁在前谁先执行)
发表于 2021-11-02 20:03:02 回复(3)
为啥不能控制?可以控制类什么时候加载不就控制了静态代码块什么时候执行吗?
发表于 2019-05-08 21:46:48 回复(0)
父类的(静态成员变量、静态初始化块)>子类的(静态成员变量、静态初始化块)>父类的(成员变量、初始化块、构造器)>子类的(成员变量、初始化块、构造器),其中,静态成员变量和静态初始化块谁在前谁先初始化
发表于 2018-12-16 23:10:37 回复(0)
我只想说,调用static final修饰的成员变量,不会造成类加载,也就不会调用静态块
发表于 2021-11-15 23:24:19 回复(0)
B选项,在创建第一个实例前或引用任何静态成员之前,将自动调用静态初始化块来初始化。
“”任何静态成员“”这句感觉有问题,如果引用的是父类的静态成员,是不会调用静态初始化块的
发表于 2020-04-01 15:39:06 回复(0)
鸡你太美
发表于 2019-04-16 09:24:51 回复(1)
b引用final static 域的时候并不会引起静态代码块的初始化阿
发表于 2017-11-29 10:20:47 回复(1)
感觉不这题太严谨:
调用 static final int a=100;静态初始化块不会被执行。所以B选项不严谨!
编辑于 2022-06-22 15:22:29 回复(0)