Java 使用继承时,静态块和初始化块的执行顺序是什么?
我有两个班:父母班和孩子班Java 使用继承时,静态块和初始化块的执行顺序是什么?,java,inheritance,constructor,static-block,Java,Inheritance,Constructor,Static Block,我有两个班:父母班和孩子班 public class Parent { public Parent() { System.out.println("Parent Constructor"); } static { System.out.println("Parent static block"); } { System.out.println("Parent initialis
public class Parent {
public Parent() {
System.out.println("Parent Constructor");
}
static {
System.out.println("Parent static block");
}
{
System.out.println("Parent initialisation block");
}
}
public class Child extends Parent {
{
System.out.println("Child initialisation block");
}
static {
System.out.println("Child static block");
}
public Child() {
System.out.println("Child Constructor");
}
public static void main(String[] args) {
new Child();
}
}
上述代码的输出将是
Parent static block
Child static block
Parent initialization block
Parent Constructor
Child initialization block
Child Constructor
为什么Java会按这种顺序执行代码?决定执行顺序的规则是什么?有几个规则在起作用
- 静态块总是在创建对象之前运行,因此您可以看到来自父静态块和子静态块的打印消息
- 现在,当您调用子类(child)的构造函数时,该构造函数隐式地调用
super()代码>在执行它自己的构造函数之前。初始化块甚至在构造函数调用之前就开始起作用,所以它首先被调用。所以现在您的父类已经创建,程序可以继续创建子类,子类将经历相同的过程
java中的静态块在main方法之前执行。若我们在java类中声明一个静态块,它将在类加载时执行。这是用静态变量初始化的。它主要用于JDBC。java中的静态块每次加载类时都会执行。这也称为静态初始化块。java中的静态块在类加载到内存时初始化,这意味着JVM读取字节码时。初始化可以是任何东西;它可以是变量初始化,也可以是该类的所有对象共享的任何其他内容。静态块是用大括号{}括起来的普通代码块,前面有Static关键字 所以先执行静态块 实例初始化块:每次创建类的实例时运行 所以,在创建类的实例时执行下一个初始化块
然后,构造函数执行了第一个只运行子类(注释extend子句)来查看简单流 第二,去阅读那边被接受的答案 编辑:
静态块在类加载到JVM时执行。而init block被复制到构造函数中,该构造函数的对象将被创建并在创建对象之前运行。使用一个分步调试程序检查对象构造过程将非常有帮助,在这个视图中,您可以看到对象是如何通过各个阶段运行的。我发现这对于从更高的角度澄清观点非常有用。Eclipse可以帮助您实现这一点,它的调试器一步到位功能。我以可视化方式学习,因此这里是顺序的可视化表示,如下所示:
公共类示例{
静止的{
步骤(1);
}
公共静态int步骤2=步骤(2);
公共int步骤8=步骤(8);
公共示例(int未使用){
超级();
步骤(10);
}
{
步骤(9);
}
//仅出于演示目的:
公共静态整数步(整数步){
System.out.println(“步骤”+步骤);
返回步骤;
}
}
公共类Example子类扩展示例{
{
步骤(11);
}
公共静态int步骤_3=步骤(3);
公共int第12步=第(12)步;
静止的{
步骤(4);
}
公共示例子类(int未使用){
super(步骤(7));
步骤(13);
}
公共静态void main(字符串[]args){
步骤(5);
新示例子类(步骤(6));
步骤(14);
}
}
这张照片是:
步骤1
步骤2
步骤3
步骤4
步骤5
步骤6
步骤7
步骤8
步骤9
步骤10
步骤11
步骤12
步骤13
步骤14
请记住,静态
部件的顺序很重要;回顾一下Example
的static
stuff和ExampleSubclass
的顺序之间的区别
还请注意,实例初始化块总是在构造函数中的super()
调用之后立即执行(即使该调用是隐含的/省略的),无论顺序如何。但是,初始化块和字段初始值设定项之间的顺序并不重要。控制流是-
静态块->初始化块->最后是构造函数。
静态块->当控件到达类时,该静态块只执行一次(JVM加载该类)
初始化块->每当为类创建新对象时,就会执行此初始化块(它将从构造函数的第二条语句开始执行,然后从后面的构造函数语句开始执行-记住构造函数的第一条语句将是Super()/This())
构造函数->每当创建一个新对象时,都会得到它。只是想分享我的发现。 我在另一个线程的一个答案中读到,静态块首先在静态字段之前执行,这是不正确的。这取决于哪个先到,静态字段还是静态块。看看下面的代码。它将努力把事情放在正确的角度
class TestLab {
static int method(String a) {
System.out.println("in static method of TestLab" + " Coming from " + a);
System.out.println("b is " + b);
return 6;
}
static int a = method("Line 11");
static int b = 7;
TestLab() {
System.out.println("Inside test lab constructor");
}
static {
System.out.println("In static block of TestLab");
}
}
public class Test1 {
public static void main(String[] args) {
System.out.println("inside main method of Test 1");
int a = TestLab.method("Line 26");
}
// static Test ref=new Test();
Test1() {
System.out.println("Default Constructor of Test1");
}
{
System.out.println("In instance block of Test1");
}
static int d = TestLab.method("Line 37");
static int e = methodOfTest1();
static {
System.out.println("In Static Block of Test1");
}
static int methodOfTest1() {
System.out.println("inside static method:mehtodOfTest1()");
return 3;
}
}
in static method of TestLab Coming from Line 11
b is 0
In static block of TestLab
in static method of TestLab Coming from Line 37
b is 7
inside static method:mehtodOfTest1()
In Static Block of Test1
inside main method of Test 1
in static method of TestLab Coming from Line 26
b is 7