有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java什么是初始化块?

我们可以将代码放入构造函数、方法或初始化块中。初始化块的用途是什么?每个java程序都必须有它吗


共 (6) 个答案

  1. # 1 楼答案

    想补充@aioobe的答案吗

    执行顺序:

    1. 超类的静态初始化块

    2. 类的静态初始化块

    3. 超级类的实例初始化块

    4. 超类的构造函数

    5. 类的实例初始化块

    6. 类的构造函数

    还有几点需要记住(第一点是重复@aioobe的答案):

    1. 静态初始化块中的代码将在类加载时执行(是的,这意味着每个类加载只执行一次),在构建任何类实例和调用任何静态方法之前执行

    2. 实例初始化块实际上由Java编译器复制到类的每个构造函数中。因此,每次实例中的代码初始化块在构造函数中的代码之前执行

  2. # 2 楼答案

    除了前面的答案中所说的,块可以是^{。。我从来没有觉得我需要使用它,然而,它就在那里

  3. # 3 楼答案

    艾奥比的回答很好 再加几点

    public class StaticTest extends parent {
        static {
            System.out.println("inside satic block");
        }
    
        StaticTest() {
            System.out.println("inside constructor of child");
        }
    
        {
            System.out.println("inside initialization block");
        }
    
        public static void main(String[] args) {
            new StaticTest();
            new StaticTest();
            System.out.println("inside main");
        }
    }
    
    class parent {
        static {
            System.out.println("inside parent Static block");
        }
        {
            System.out.println("inside parent initialisation block");
        }
    
        parent() {
            System.out.println("inside parent constructor");
        }
    }
    

    这给

    inside parent Static block
    inside satic block
    inside parent initialisation block
    inside parent constructor
    inside initialization block
    inside constructor of child
    inside parent initialisation block
    inside parent constructor
    inside initialization block
    inside constructor of child
    inside main
    

    这就像是在陈述显而易见的事情,但似乎更清楚一点

  4. # 4 楼答案

    Initializer block contains the code that is always executed whenever an instance is created. It is used to declare/initialise the common part of various constructors of a class.

    初始化构造函数和初始化程序块的顺序无关紧要,初始化程序块总是在构造函数之前执行

    如果我们想对一个类的所有对象执行一次代码怎么办

    我们在Java中使用静态块

  5. # 5 楼答案

    首先,有两种类型的initialization blocks

    • 实例初始化块,以及
    • 静态初始化块

    此代码应说明它们的使用以及它们的执行顺序:

    public class Test {
    
        static int staticVariable;
        int nonStaticVariable;        
    
        // Static initialization block:
        // Runs once (when the class is initialized)
        static {
            System.out.println("Static initalization.");
            staticVariable = 5;
        }
    
        // Instance initialization block:
        // Runs each time you instantiate an object
        {
            System.out.println("Instance initialization.");
            nonStaticVariable = 7;
        }
    
        public Test() {
            System.out.println("Constructor.");
        }
    
        public static void main(String[] args) {
            new Test();
            new Test();
        }
    }
    

    印刷品:

    Static initalization.
    Instance initialization.
    Constructor.
    Instance initialization.
    Constructor.
    

    如果希望运行某些代码,而不管使用哪个构造函数,或者希望对匿名类执行某些实例初始化,则实例初始化块非常有用

  6. # 6 楼答案

    示例代码在这里被认可为答案,它是正确的,但我不同意。它没有显示正在发生的事情,我将向您展示一个很好的示例,以了解JVM实际上是如何工作的:

    package test;
    
        class A {
            A() {
                print();
            }
    
            void print() {
                System.out.println("A");
            }
        }
    
        class B extends A {
            static int staticVariable2 = 123456;
            static int staticVariable;
    
            static
            {
                System.out.println(staticVariable2);
                System.out.println("Static Initialization block");
                staticVariable = Math.round(3.5f);
            }
    
            int instanceVariable;
    
            {
                System.out.println("Initialization block");
                instanceVariable = Math.round(3.5f);
                staticVariable = Math.round(3.5f);
            }
    
            B() {
                System.out.println("Constructor");
            }
    
            public static void main(String[] args) {
                A a = new B();
                a.print();
                System.out.println("main");
            }
    
            void print() {
                System.out.println(instanceVariable);
            }
    
            static void somethingElse() {
                System.out.println("Static method");
            }
        }
    

    在开始评论源代码之前,我将对类的静态变量做一个简短的解释:

    首先,它们被称为类变量,它们属于类而不是类的特定实例。该类的所有实例都共享此静态(类)变量。每个变量都有一个默认值,具体取决于基元或引用类型。另一件事是,当您在类的一些成员(初始化块、构造函数、方法、属性)中重新分配静态变量时,您更改的是静态变量的值,而不是针对特定实例,而是针对所有实例。为了总结静态部分,我将说,类的静态变量不是在您第一次实例化类时创建的,而是在您定义类时创建的,它们存在于JVM中,不需要任何实例。因此,从外部类(未定义静态成员的类)正确访问静态成员是通过使用点后面的类名,然后是要访问的静态成员(模板:<CLASS_NAME>.<STATIC_VARIABLE_NAME>

    现在让我们看看上面的代码:

    入口点是主要方法——只有三行代码。我想参考一下目前被批准的例子。根据它,在打印“静态初始化块”之后必须打印的第一件事是“初始化块”,我不同意,非静态初始化块不是在构造函数之前调用的,它是在定义初始化块的类的构造函数的任何初始化之前调用的。当你创建一个对象(类的实例)时,首先要涉及类的构造函数,然后当你进入构造函数时,调用的第一部分要么是隐式(默认)超级构造函数,要么是显式超级构造函数,要么是对另一个重载构造函数的显式调用(但在某个时刻,如果有一个重载构造函数链,最后一个构造函数会隐式或显式地调用超级构造函数)

    有一个对象的多态创建,但在进入类B及其主方法之前,JVM初始化所有类(静态)变量,然后经过静态初始化块(如果存在),然后进入类B并开始执行主方法。它转到类B的构造函数,然后使用多态性立即(隐式)调用类A的构造函数。在类A的构造函数体中调用的方法(重写方法)是在类B中定义的方法,在这种情况下,在重新初始化之前使用名为instanceVariable的变量。关闭类B的构造函数后,线程返回到类B的构造函数,但在打印“构造函数”之前,它首先进入非静态初始化块。为了更好地理解用IDE调试它,我更喜欢Eclipse