Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么是初始化块?_Java_Constructor_Initialization_Initialization Block - Fatal编程技术网

Java 什么是初始化块?

Java 什么是初始化块?,java,constructor,initialization,initialization-block,Java,Constructor,Initialization,Initialization Block,我们可以将代码放入构造函数、方法或初始化块中。初始化块的用途是什么?每个java程序都必须有它吗 初始化块在初始化类时和调用构造函数之前执行。它们通常放置在大括号中的构造函数上方。在你的课堂上根本没有必要把它们包括在内 它们通常用于初始化引用变量。这是一个很好的解释这个问题并不完全清楚,但这里简要介绍了初始化对象中数据的方法。假设您有一个类a,它包含一个对象列表 1) 在字段声明中输入初始值: class A { private List<Object> data = new

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

初始化块在初始化类时和调用构造函数之前执行。它们通常放置在大括号中的构造函数上方。在你的课堂上根本没有必要把它们包括在内


它们通常用于初始化引用变量。这是一个很好的解释

这个问题并不完全清楚,但这里简要介绍了初始化对象中数据的方法。假设您有一个类a,它包含一个对象列表

1) 在字段声明中输入初始值:

class A {
    private List<Object> data = new ArrayList<Object>();
}
A类{
私有列表数据=新的ArrayList();
}
2) 在构造函数中指定初始值:

class A {
    private List<Object> data;
    public A() {
        data = new ArrayList<Object>();
    }
}
A类{
私人名单数据;
公共A(){
数据=新的ArrayList();
}
}
这两种方法都假定您不希望将“数据”作为构造函数参数传递

如果将重载构造函数与上述内部数据混合使用,事情会变得有点棘手。考虑:

class B {
    private List<Object> data;
    private String name;
    private String userFriendlyName;

    public B() {
        data = new ArrayList<Object>();
        name = "Default name";
        userFriendlyName = "Default user friendly name";
    }

    public B(String name) {
        data = new ArrayList<Object>();
        this.name = name;
        userFriendlyName = name;
    }

    public B(String name, String userFriendlyName) {
        data = new ArrayList<Object>();
        this.name = name;
        this.userFriendlyName = userFriendlyName;
    }
}
B类{
私人名单数据;
私有字符串名称;
私有字符串userFriendlyName;
公共图书馆B(){
数据=新的ArrayList();
name=“默认名称”;
userFriendlyName=“默认用户友好名称”;
}
公共B(字符串名称){
数据=新的ArrayList();
this.name=名称;
userFriendlyName=名称;
}
公共B(字符串名称、字符串userFriendlyName){
数据=新的ArrayList();
this.name=名称;
this.userFriendlyName=userFriendlyName;
}
}
请注意,有很多重复的代码。您可以通过使构造函数相互调用来解决此问题,也可以使用每个构造函数调用的私有初始化方法:

class B {
    private List<Object> data;
    private String name;
    private String userFriendlyName;

    public B() {
        this("Default name", "Default user friendly name");
    }

    public B(String name) {
        this(name, name);
    }

    public B(String name, String userFriendlyName) {
        data = new ArrayList<Object>();
        this.name = name;
        this.userFriendlyName = userFriendlyName;
    }
}
B类{
私人名单数据;
私有字符串名称;
私有字符串userFriendlyName;
公共图书馆B(){
此(“默认名称”、“默认用户友好名称”);
}
公共B(字符串名称){
这个(名字,名字),;
}
公共B(字符串名称、字符串userFriendlyName){
数据=新的ArrayList();
this.name=名称;
this.userFriendlyName=userFriendlyName;
}
}

B类{
私人名单数据;
私有字符串名称;
私有字符串userFriendlyName;
公共图书馆B(){
init(“默认名称”、“默认用户友好名称”);
}
公共B(字符串名称){
init(名称、名称);
}
公共B(字符串名称、字符串userFriendlyName){
init(名称,userFriendlyName);
}
私有void init(字符串_name,字符串_userFriendlyName){
数据=新的ArrayList();
this.name=名称;
this.userFriendlyName=userFriendlyName;
}
}
这两者(或多或少)是等价的

我希望这能为您提供一些关于如何初始化对象中的数据的提示。我不会谈论静态初始化块,因为目前这可能有点高级


编辑:我将您的问题解释为“如何初始化我的实例变量”,而不是“初始化程序块如何工作”,因为初始化程序块是一个相对高级的概念,从问题的语气来看,您似乎在询问更简单的概念。我可能错了。

首先,有两种类型:

  • 实例初始化块,以及
  • 静态初始化块
此代码应说明它们的使用以及它们的执行顺序:

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.

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

希望添加到@aioobe的答案中

执行顺序:

  • 超类的静态初始化块

  • 类的静态初始化块

  • 超类的实例初始化块

  • 超类的构造函数

  • 类的实例初始化块

  • 类的构造函数

  • 需要记住的另外几点(第1点是重复@aioobe的答案):

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

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


  • 示例代码(在这里被批准为答案)是正确的,但我不同意。它没有显示发生了什么,我将向您展示一个很好的示例,以了解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中,不需要任何实例
    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");
            }
        }
    
    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
    
    public class StaticInitializationBlock {
    
        static int staticVariable;
        int instanceVariable;
    
        // Static Initialization Block
        static { 
            System.out.println("Static block");
            staticVariable = 5;
    
        }
    
        // Instance Initialization Block
        { 
    
            instanceVariable = 7;
            System.out.println("Instance Block");
            System.out.println(staticVariable);
            System.out.println(instanceVariable);
    
            staticVariable = 10;
        }
    
    
        public StaticInitializationBlock() { 
    
            System.out.println("Constructor");
        }
    
        public static void main(String[] args) {
            new StaticInitializationBlock();
            new StaticInitializationBlock();
        }
    
    }
    
    Static block
    Instance Block
    5
    7
    Constructor
    Instance Block
    10
    7
    Constructor
    
    abstract class Aircraft {
    
        protected Integer seatCapacity;
    
        {   // Initial block 1, Before Constructor
            System.out.println("Executing: Initial Block 1");
        }
    
        Aircraft() {
            System.out.println("Executing: Aircraft constructor");
        }
    
        {   // Initial block 2, After Constructor
            System.out.println("Executing: Initial Block 2");
        }
    
    }
    
    class SupersonicAircraft extends Aircraft {
    
        {   // Initial block 3, Internalizing a instance variable
            seatCapacity = 300;
            System.out.println("Executing: Initial Block 3");
        }
    
        {   // Initial block 4
            System.out.println("Executing: Initial Block 4");
        }
    
        SupersonicAircraft() {
            System.out.println("Executing: SupersonicAircraft constructor");
        }
    }
    
    Executing: Initial Block 1
    Executing: Initial Block 2
    Executing: Aircraft constructor
    Executing: Initial Block 3
    Executing: Initial Block 4
    Executing: SupersonicAircraft constructor
    Seat Capacity - 300