简体   繁体   English

Java中的执行顺序

[英]Order of execution in Java

I am trying to understand this example from Thinking in Java : 我试图从Thinking in Java中理解这个例子

package c07;
import com.bruceeckel.simpletest.*;

class Meal {
    Meal() { System.out.println("Meal()"); }
}

class Bread {
    Bread() { System.out.println("Bread()"); }
}

class Cheese {
    Cheese() { System.out.println("Cheese()"); }
}

class Lettuce {
    Lettuce() { System.out.println("Lettuce()"); }
}

class Lunch extends Meal {
    Lunch() { System.out.println("Lunch()"); }
}

class PortableLunch extends Lunch {
    PortableLunch() { System.out.println("PortableLunch()");}
}

public class Sandwich extends PortableLunch {
    private static Test monitor = new Test();
    private Bread b = new Bread();
    private Cheese c = new Cheese();
    private Lettuce l = new Lettuce();

    public Sandwich() {
        System.out.println("Sandwich()");
    }

    public static void main(String[] args) {
        new Sandwich();
        monitor.expect(new String[] {
          "Meal()",
          "Lunch()",
          "PortableLunch()",
          "Bread()",
          "Cheese()",
          "Lettuce()",
          "Sandwich()"
        });
    }
}

As I understand from Java Language Specification, the order of execution begins by loading the class containing the main method. 据我所知,从Java语言规范,执行顺序从加载包含main方法的类开始。 Then all the statics and member variables of this class must be initialized (before which all the member variables of the superclasses must be intialized, although there are none of those in this case). 然后必须初始化此类的所有静态和成员变量(在此之前必须初始化超类的所有成员变量,尽管在这种情况下没有这些变量)。

So I thought b , c , l would be initialized before main starts executing. 所以我认为bcl会在main开始执行之前被初始化。 That does not seem to be the case from the output though. 但是,输出似乎并非如此。 Am I missing something? 我错过了什么吗?

No, b and c are instance variables. 不, bc实例变量。

There's no automatic instantiation of the class containing main . 没有包含main的类的自动实例化。 Only static variables are initialized. 仅初始化静态变量。 It's just as if some outside caller wrote: 这就好像一些外部来电者写道:

Sandwich.main(args);

So when you wrote: 所以当你写道:

Then all the statics and member variables of this class must be initialized 然后必须初始化此类的所有静态和成员变量

... that was wrong. 那是错的。 Only the static variables are initialized - just as normal. 只初始化静态变量 - 正常情况下。

The example output is correct. 示例输出是正确的。 Here are the important rules: 以下是重要规则:

  • when the class is created, the constructor of the super class has to be called first. 在创建类时,必须首先调用超类的构造函数。 This bubbles up to Object class 这冒泡到Object

  • before the constructor is called, member variable initialization is called. 在调用构造函数之前,调用成员变量初始化。

No static s are involved in this example, except the technical monitor . 除技术monitor外,此示例中不涉及static

JLS # 12.4.1. JLS#12.4.1。 When Initialization Occurs 发生初始化时

A class or interface type T will be initialized immediately before the first occurrence of any one of the following: 类或接口类型T将在第一次出现以下任何一个之前立即初始化:

  • T is a class and an instance of T is created. T是一个类,并且创建了T的实例。
  • T is a class and a static method declared by T is invoked. T是一个类,并且调用由T声明的静态方法。
  • A static field declared by T is assigned. 分配由T声明的静态字段。
  • A static field declared by T is used and the field is not a constant variable (§4.12.4). 使用由T声明的静态字段,该字段不是常量变量(第4.12.4节)。
  • T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed. T是顶级类(第7.6节),并且执行在词典内嵌套在T(第8.1.3节)内的断言语句(第14.10节)。

JLS # 12.5. JLS#12.5。 Creation of New Class Instances 创建新的类实例

Whenever a new class instance is created, memory space is allocated for it with room for all the instance variables declared in the class type and all the instance variables declared in each superclass of the class type, including all the instance variables that may be hidden (§8.3). 每当创建一个新的类实例时,就会为它分配内存空间,为类类型中声明的所有实例变量提供空间,并在类类型的每个超类中声明所有实例变量,包括可能隐藏的所有实例变量( §8.3)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM