【问题标题】:The execute order of the static method(JAVA) [duplicate]静态方法的执行顺序(JAVA)[重复]
【发布时间】:2016-11-20 03:28:49
【问题描述】:

我在网上搜索了很长时间。但是没有用。请帮助或尝试给出一些想法如何实现这一点?为什么结果不是首先打印“int main”?我想知道为什么这个程序的结果如下?提前谢谢。

超级静态块

静态块 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(); 
        }
    }

【问题讨论】:

    标签: java methods static


    【解决方案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 类中的任何内容。

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

    【讨论】:

    • 真诚感谢您的回答。看了您的文章,有个疑问:子类的non_field在我们调用子类的构造函数之前就已经初始化了,是不是可以'我们不是从构造函数中调用non_field吗?我不明白。
    • 对此我感到很抱歉,我打错了问题。问题是为什么我们不应该从构造函数调用非最终方法(。我已经阅读了你的文章,我有一个问题: 子类的non_field在我们调用子类的构造函数之前就被初始化了,对吗?那为什么不能从构造函数中调用非final方法呢?我不明白)
    • @Manhand 我已经用代码更新了我的答案,以解释为什么不建议在构造函数中调用非最终方法。检查一下。
    【解决方案2】:

    顺序如下:

    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. 子类构造函数打印“constructor”

    【讨论】:

    • 真诚感谢您的回答。请问静态字段是否会在静态方法之前初始化?
    • 静态字段被初始化为类静态初始化的一部分。所以是的。
    猜你喜欢
    • 2015-09-05
    • 1970-01-01
    • 2022-12-22
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    相关资源
    最近更新 更多