2016-11-20 168 views
-1

我在网上搜索了很长时间。但没用。请帮助或尝试提供一些想法如何实现此目的?为什么结果不是在第一个打印“int main”?我想知道的是为什么这个程序的结果如下?预先感谢。静态方法的执行顺序(JAVA)

超静块

静块4

在主

超级构造

构造

class StaticSuper { 
     static { 
      System.out.println("super static block"); 
     } 


     StaticSuper() { 
      System.out.println("super constructor");  
     } 
    } 

    public class StaticTests extends StaticSuper { 
     static int rand; 

     //static initialise 
     static {   
     rand = (int) (Math.random() * 6); 
     System.out.println("static block " + rand);  
     } 

     StaticTests() { 
      System.out.println("constructor"); 
     } 

     public static void main(String[] args) { 
      System.out.println("in main"); 
      StaticTests st = new StaticTests(); 
     } 
    } 

回答

1

点火次序是:

  1. 父的静止象素块和字段中出现的顺序
  2. 儿童的静止象素块和字段,以便外观
  3. 父非静态字段初始
  4. 父构造

  5. 儿童非静电场初始化器

  6. 儿童构造函数

你可以阅读更多关于here


更新:

运行这一点,你就会明白,为什么你不应该调用父类的构造函数非final方法。

public class Derived extends Super 

{ 

    @Override 
    void initialise() 
    { 
     System.out.println("Now you can't initialise field \"a\" anymore"); 
    } 
    Derived() 
    { 

    } 
    public static void main(String[] args) 
    { 
     Derived d = new Derived(); 

    } 
} 

class Super 
{ 
    private int a; 
    void initialise() 
    { 
     a = 10; 
    } 
    Super() 
    { 
     initialise(); 
    } 
} 

所以你不能初始化你的领域a了它可能会破坏你的super类代码。

final方法不能被覆盖。因此,您可以初始化a字段,并且不会破坏super课程中的任何内容。

我希望它能澄清你的疑问。

+0

谢谢您的回答sincerely.I已经看了你的文章,我有一个问题:我们所说的构造函数之前子类的non_field初始化子类,是不是?我们为什么不能从构造函数中调用non_field?我不理解它。 – Manhand

+0

我对此感到很抱歉,我输入的问题是错误的。问题是为什么我们不应该从构造函数中调用非final方法(。我已经阅读过您的文章,并且有一个问题:子类的non_field是在我们调用子类的构造函数之前进行初始化,是不是?我们为什么不能从构造函数中调用非final方法?我不明白) – Manhand

+0

@Manhand我用代码更新了我的答案,以解释为什么它不建议在构造函数中调用非final方法。核实。 – SkrewEverything

1

的顺序如下:

  1. 您键入java StaticTests

  2. 的JVM加载StaticTests

  3. JVM找到static void main(String[])方法并尝试调用它。

  4. main(...)的调用触发了StaticTests的静态初始化。 (一个类在第一次调用静态方法之前被初始化。)

  5. StaticTests的静态初始化触发了StaticSuper的静态初始化。 (在类初始化之前,必须初始化一个类的超类。)

  6. “超级静态块”由超静态初始化打印。

  7. “静态块4”由子类static init打印。

  8. main(...)通话开始。

  9. 执行System.out.println("in main")语句,打印“in main”。

  10. new StaticTests调用构造函数StaticTests

  11. StaticTests构造函数隐式调用super()。 (普通的Java行为)

  12. 超类构造函数打印“超级构造函数”。

  13. 子类构造函数打印“构造”

+0

谢谢你的回答,如果静态方法之前静态字段将被初始化? – Manhand

+0

静态字段被初始化为类静态初始化的一部分。所以是的。 –