我有两个班级父母和孩子
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按该顺序执行代码?确定执行顺序的规则是什么?
答案 0 :(得分:49)
有几个规则在起作用
super();
。初始化块甚至在构造函数调用之前就会发挥作用,因此这就是它首先被调用的原因。所以现在创建了父级,程序可以继续创建将经历相同过程的子类。 <强>说明:强>
- 首先执行父块的静态块,因为它首先加载,并且在加载类时调用静态块。
醇>
答案 1 :(得分:42)
我在视觉上学习,所以这里是一个顺序的直观表示,作为SSCCE:
public class Example {
static {
step(1);
}
public static int step_1 = step(2);
public int step_6 = step(6);
public Example() {
step(8);
}
{
step(7);
}
// Just for demonstration purposes:
public static int step(int step) {
System.out.println("Step " + step);
return step;
}
}
public class ExampleSubclass extends Example {
{
step(9);
}
public static int step_3 = step(3);
public int step_10 = step(10);
static {
step(4);
}
public ExampleSubclass() {
step(11);
}
public static void main(String[] args) {
step(5);
new ExampleSubclass();
step(12);
}
}
打印:
Step 1
Step 2
Step 3
Step 4
Step 5
Step 6
Step 7
Step 8
Step 9
Step 10
Step 11
Step 12
请记住static
部分的顺序很重要;回顾Example
的{{1}}内容与static
的顺序之间的差异。
另请注意,无论顺序如何,实例初始化块始终在构造函数之前执行。但是,顺序在初始化块和字段初始化程序之间确实很重要。
答案 2 :(得分:10)
首先运行子类(注释extend子句)以查看简单流程。
秒 - 转到Static block vs. initializer block in Java?&amp;阅读那里接受的答案。
编辑:
答案 3 :(得分:5)
java中的静态块在main方法之前执行。如果我们在java类中声明一个静态块,它将在类加载时执行。这是使用静态变量初始化的。它主要用于JDBC。每次加载类时都会执行java中的静态块。这也称为静态初始化块。 java中的静态块在类加载到内存时初始化,这意味着当JVM读取字节码时。初始化可以是任何东西;它可以是变量初始化或该类的所有对象应该共享的任何其他内容。静态块是用大括号{}括起来的普通代码块,前面是静态关键字。
首先执行静态块。
实例初始化块:每次创建类的实例时运行。
所以当创建类的实例时执行下一个初始化块。
然后执行构造函数
答案 4 :(得分:5)
(在您的代码中,将首先执行父静态块,然后再执行子类静态块。)
在代码中创建子对象时:
答案 5 :(得分:3)
通过一步一步的debuger来结束对象构建过程将非常有帮助,其中有一个视图,您可以在其中查看对象如何在阶段中进行操作。我发现这对于从更高的角度清除视角非常有用。 Eclipse可以通过它的调试器步骤来帮助您实现这一功能。
答案 6 :(得分:3)
只是想分享我的发现。 我在另一个线程中的一个答案中读到静态块首先在静态字段之前执行,这是不正确的。这取决于哪个是第一个,静态字段或静态块。看看下面的代码。它会试图把事情放在眼里。
回到主要方法。
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
答案 7 :(得分:3)
这是我在准备认证时发现的。
当我们运行一个类时,首先发生静态块/静态变量初始化。如果有多个静态块,它将按照它出现的顺序执行它,
然后它将执行init blocks / instance variable initialisation。如果存在多个init块/变量初始化,它将按照它出现的顺序执行它,
之后它会查看构造函数。
答案 8 :(得分:1)
控制流程是 -
静态阻止 - &gt;初始化块 - &gt;最后是构造函数。
静态块 - &gt;当控件进入类时,此静态块将仅执行 。(JVM加载此类)
初始化块 - &gt;只要为类 创建一个新对象,就会执行此初始化块(它将从构造函数的第二个语句执行,然后执行构造函数语句 - 记住构造函数的第一个语句将是Super()/ this ()) 强>
构造函数 - &gt;每当创建一个新对象时都会得到它。
答案 9 :(得分:0)
将类加载到JVM中时会执行静态块。当init块被复制到构造函数中时,它将创建对象并在创建对象之前运行。
答案 10 :(得分:0)
1。静态初始化块仅在类加载时执行。 2.Init块每次在创建类的对象之前执行。