developer tip

초기화 블록이란 무엇입니까?

copycodes 2020. 8. 31. 07:59
반응형

초기화 블록이란 무엇입니까?


생성자, 메서드 또는 초기화 블록에 코드를 넣을 수 있습니다. 초기화 블록의 용도는 무엇입니까? 모든 Java 프로그램에 있어야합니까?


먼저 두 가지 유형의 초기화 블록이 있습니다 .

  • 인스턴스 초기화 블록
  • 정적 초기화 블록 .

이 코드는 그것들의 사용법과 실행 순서를 보여 주어야합니다 :

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. 슈퍼 클래스의 정적 초기화 블록

  2. 클래스의 정적 초기화 블록

  3. 슈퍼 클래스의 인스턴스 초기화 블록

  4. 슈퍼 클래스 생성자

  5. 클래스의 인스턴스 초기화 블록

  6. 클래스의 생성자.

명심해야 할 몇 가지 추가 사항 (포인트 1은 @aioobe의 답변을 반복 함) :

  1. 정적 초기화 블록의 코드는 클래스의 인스턴스가 생성되기 전과 정적 메서드가 호출되기 전에 클래스로드시 (즉, 클래스로드 당 한 번만 실행 됨) 실행됩니다.

  2. 인스턴스 초기화 블록은 실제로 Java 컴파일러에 의해 클래스가 가진 모든 생성자로 복사됩니다. 따라서 인스턴스 초기화 블록 의 코드가 생성자의 코드 바로 전에 실행될 때마다 .


aioobe가 몇 점 더 추가하여 좋은 대답

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

그것은 명백한 것을 말하는 것과 같지만 조금 더 명확 해 보입니다.


여기에 답변으로 승인 된 샘플 코드는 정확하지만 동의하지 않습니다. 무슨 일이 일어나고 있는지 보여주지 않으며 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");
        }
    }

소스 코드에 대한 주석 달기를 시작하기 전에 클래스의 정적 변수에 대해 간략하게 설명하겠습니다.

먼저 클래스 변수라고하며 클래스의 특정 인스턴스가 아닌 클래스에 속합니다. 클래스의 모든 인스턴스는이 static (class) 변수를 공유합니다. 각 변수에는 기본 또는 참조 유형에 따라 기본값이 있습니다. 또 다른 것은 클래스의 일부 멤버 (초기화 블록, 생성자, 메서드, 속성)에서 정적 변수를 재 할당 할 때 특정 인스턴스가 아닌 정적 변수의 값을 변경하는 것입니다. 인스턴스. 정적 부분을 마무리하기 위해 클래스의 정적 변수는 클래스를 처음 인스턴스화 할 때 생성되지 않고 클래스를 정의 할 때 생성되며 인스턴스가 필요없이 JVM에 존재한다고 말할 것입니다.<CLASS_NAME>.<STATIC_VARIABLE_NAME>).

이제 위의 코드를 살펴 보겠습니다.

진입 점은 주요 방법입니다. 코드는 세 줄뿐입니다. 현재 승인 된 예를 참조하고 싶습니다. 이에 따르면 "정적 초기화 블록"을 인쇄 한 후 가장 먼저 인쇄해야하는 것은 "초기화 블록"이고 여기에 동의하지 않습니다. 비 정적 초기화 블록은 생성자 전에 호출되지 않고 생성자 초기화 전에 호출됩니다. 초기화 블록이 정의 된 클래스의.

객체의 다형성 생성이 있지만 클래스 B와 기본 메소드에 들어가기 전에 JVM은 모든 클래스 (정적) 변수를 초기화 한 다음 정적 초기화 블록이있는 경우이를 통과 한 다음 클래스 B에 들어가 주요 방법의 실행. 클래스 B의 생성자로 이동 한 다음 즉시 (암시 적으로) 클래스 A의 생성자를 호출합니다. 다형성을 사용하여 클래스 A의 생성자의 본문에서 호출 된 메서드 (재정의 된 메서드)가 클래스 B에서 정의 된 것입니다. 다시 초기화하기 전에 instanceVariable이라는 변수가 사용됩니다. 클래스 B의 생성자를 닫은 후 스레드는 클래스 B의 생성자에게 반환되지만 "Constructor"를 인쇄하기 전에 먼저 비 정적 초기화 블록으로 이동합니다. 더 나은 이해를 위해 일부 IDE로 디버그하십시오.


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.

The order of initialization constructors and initializer block doesn’t matter, initializer block is always executed before constructor.

What if we want to execute some code once for all objects of a class?

We use Static Block in Java.


Initialization blocks are executed whenever the class is initialized and before constructors are invoked. They are typically placed above the constructors within braces. It is not at all necessary to include them in your classes.

They are typically used to initialize reference variables. This page gives a good explanation


The question is not entirely clear, but here's a brief description of ways you can initialise data in an object. Let's suppose you have a class A that holds a list of objects.

1) Put initial values in the field declaration:

class A {
    private List<Object> data = new ArrayList<Object>();
}

2) Assign initial values in the constructor:

class A {
    private List<Object> data;
    public A() {
        data = new ArrayList<Object>();
    }
}

These both assume that you do not want to pass "data" as a constructor argument.

Things get a little tricky if you mix overloaded constructors with internal data like above. Consider:

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;
    }
}

Notice that there is a lot of repeated code. You can fix this by making constructors call each other, or you can have a private initialisation method that each constructor calls:

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;
    }
}

or

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

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

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

    public B(String name, String userFriendlyName) {
        init(name, userFriendlyName);
    }

    private void init(String _name, String _userFriendlyName) {
        data = new ArrayList<Object>();
        this.name = name;
        this.userFriendlyName = userFriendlyName;
    }
}

The two are (more or less) equivalent.

I hope that gives you some hints on how to initialise data in your objects. I won't talk about static initialisation blocks as that's probably a bit advanced at the moment.

EDIT: I've interpreted your question as "how do I initialise my instance variables", not "how do initialiser blocks work" as initialiser blocks are a relatively advanced concept, and from the tone of the question it seems you're asking about the simpler concept. I could be wrong.


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

}

Output:

Static block
Instance Block
5
7
Constructor
Instance Block
10
7
Constructor

참고URL : https://stackoverflow.com/questions/3987428/what-is-an-initialization-block

반응형