简体   繁体   English

请在Java中解释此行为

[英]Please explain this behaviour in java

class abc extends TestStart{
     static{
         System.out.println("c");
     }
     {
         System.out.println("f");
     }
     public abc(){
         System.out.println("d");
     }
}

public class TestStart {
     static {
         System.out.println("A");
     }
     {
         System.out.println("z");
     }
     public TestStart(){
         System.out.println("b");
     }

     public static void main(String[] args) {

         TestStart x = new abc();
         TestStart y = new TestStart();             
     }
}

Output-----------> A czbfdzb 输出-----------> czbfdzb

I think output behaviour for this ---->>>>> TestStart x = new abc(); 我认为此---- >>>>> TestStart的输出行为x = new abc(); --------should be :- - - - - 应该 :-

  1. First static block of both classes will run 这两个类的第一个静态块将运行
  2. Then init block of child class will called because of new abc().But here init of parent class is getting called 然后子类的init块会因为新的abc()而被调用。但是这里父类的init被调用了
  3. Then super() is invoked from new abc() which results in call to parent class constructor. 然后从新的abc()中调用super(),从而导致对父类构造函数的调用。
  4. before parent class constructor ,init block of parent class will execute. 在父类构造函数之前,将执行父类的init块。
  5. then constructor of parnet class will execute 然后parnet类的构造函数将执行
  6. then constructor of child class will execute. 然后子类的构造函数将执行。

I should get the following output: A cfzbdzb 我应该得到以下输出:cfzbdzb

This behaviour is largely derived from if there are no init block in parent class and child class. 如果在父类和子类中没有init块,则此行为很大程度上是从此派生的。 Please explain the output that I have mentioned. 请解释我提到的输出。

You got: A c z b f d z b while you expected: A c f z b d z b 您得到了: A c z b f d z b而您却期望: A c f z b d z b

So, you are saying that you expected f to happen before z b . 因此,您说的是您希望fz b之前发生。

So, what you are essentially saying is that you expected: 因此,您实际上要说的是您期望的:

  • an instance initializer of the most derived class ( f ) 最派生类( f )的实例初始化器

to be invoked before 在之前被调用

  • an instance initializer of the base class ( z ) and 基类( z )和
  • the constructor of the base class ( b ). 基类( b )的构造函数。

Well, that's simply not how things happen. 好吧,这根本不是事情发生的方式。 All of the instance initialization of the base class must be completed before instance initialization of the derived class begins, otherwise the derived class would be able to access uninitialized members of the base class. 基类的所有实例初始化必须在派生类的实例初始化开始之前完成,否则派生类将能够访问基类的未初始化成员。

And all the static initialization stuff ( A , c ) were red herrings thrown in the question to confuse us. 并且所有静态初始化内容( Ac )都是在问题中引发的红色鲱鱼,使我们感到困惑。

After initialization static blocks and variables in all classes runs initializers of parent. 初始化后,所有类中的静态块和变量都会运行parent的初始化程序。 After parent constructor, then initializers of child in child constructor. 在父构造函数之后,然后是子构造函数中的子构造函数。 That's because You can use some parent fields in your child initializers, so they must be initialized before. 这是因为您可以在子初始化程序中使用某些父字段,因此必须在初始化之前对其进行初始化。

First, some naming: 首先,命名:

 public class TestStart {
   static { // static initializer
     System.out.println("A");
   }
   { // instance initializer
     System.out.println("z");
   }
   public TestStart() { // constructor
     System.out.println("b");
   }
 }

You are right that static initializers are called first, but the only guarantee you have is that classes static initializer is called before you use that class in any context. 没错,首先会调用静态初始值设定项,但您唯一的保证就是在任何上下文中使用该类之前都要先调用类静态初始值设定项。

For the instance initializers and constructors, the order of calling is as follows, from first called to last called: 对于实例初始化程序和构造函数,从第一次调用到最后一次调用的调用顺序如下:

Parent initializer, Parent Constructor, Your Initializer, Your Constructor

If you invoke other constructor from same class using this() , initializer is called once before the all the constructors calls in your class. 如果您使用this()从同一个类中调用其他构造函数,则在类中所有构造函数调用之前,都会调用一次初始化器。

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

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