Development Tip

정적 변수는 언제 초기화됩니까?

yourdevel 2020. 10. 24. 11:58
반응형

정적 변수는 언제 초기화됩니까?


정적 변수가 기본값으로 초기화되는시기가 궁금합니다. 클래스가로드 될 때 정적 변수가 생성 (할당) 된 다음 선언의 정적 이니셜 라이저 및 초기화가 실행되는 것이 맞습니까? 어떤 시점에서 기본값이 제공됩니까? 이것은 순방향 참조의 문제로 이어집니다.

또한 정적 필드가 시간 내에 초기화되지 않는 이유에 대한 질문을 참조하여 이것을 설명 할 수 있다면 제발 부탁드립니다 . 특히 같은 사이트에서 Kevin Brock이 제공 한 답변입니다. 세 번째 요점을 이해할 수 없습니다.


Java 정적 변수 메소드 참조 에서 :

  • 객체 (인스턴스)가 아닌 클래스에 속하는 변수입니다.
  • 정적 변수는 실행 시작시 한 번만 초기화됩니다. 이러한 변수는 인스턴스 변수를 초기화하기 전에 먼저 초기화됩니다.
  • 클래스의 모든 인스턴스에서 공유 할 단일 복사본
  • 정적 변수는 클래스 이름으로 직접 액세스 할 수 있으며 개체가 필요하지 않습니다.

인스턴스 및 클래스 (정적) 변수는 의도적으로 초기화하지 못하면 자동으로 표준 기본값으로 초기화됩니다. 지역 변수가 자동으로 초기화되지는 않지만 사용하기 전에 지역 변수를 초기화하거나 해당 지역 변수에 값을 할당하지 못하는 프로그램을 컴파일 할 수 없습니다.

컴파일러가 실제로하는 일은 클래스 선언에 나타나는 순서대로 모든 정적 변수 이니셜 라이저와 코드의 모든 정적 이니셜 라이저 블록을 결합하는 단일 클래스 초기화 루틴을 내부적으로 생성하는 것입니다. 이 단일 초기화 절차는 클래스가 처음로드 될 때 한 번만 자동으로 실행됩니다.

내부 클래스의 경우 정적 필드를 가질 수 없습니다.

내부 클래스는 명시 적 또는 암시 적으로 선언되지 않은 중첩 된 클래스입니다 static.

...

내부 클래스는 정적 이니셜 라이저 (§8.7) 또는 멤버 인터페이스를 선언 할 수 없습니다.

내부 클래스는 상수 변수가 아닌 경우 정적 멤버를 선언 할 수 없습니다.

JLS 8.1.3 내부 클래스 및 엔 클로징 인스턴스 참조

finalJava의 필드는 선언 위치와 별도로 초기화 할 수 있지만 필드에는 적용 할 수 없습니다 static final. 아래 예를 참조하십시오.

final class Demo
{
    private final int x;
    private static final int z;  //must be initialized here.

    static 
    {
        z = 10;  //It can be initialized here.
    }

    public Demo(int x)
    {
        this.x=x;  //This is possible.
        //z=15; compiler-error - can not assign a value to a final variable z
    }
}

하나 개가 있기 때문이다 사본static대신 인스턴스 변수와 우리가 초기화하려고하면 같은 유형의 각 인스턴스와 관련된보다, 유형과 관련된 변수 z유형 static final, 그것은 다시 초기화하려고 시도 생성자 내에서 static final유형 필드를 z생성자는 정적 final필드에 발생하지 않아야하는 클래스의 각 인스턴스화에서 실행되기 때문 입니다.


보다:

특히 마지막은 정적 변수가 초기화되는시기와 순서설명 하는 자세한 초기화 단계제공합니다 ( final컴파일 시간 상수 인 클래스 변수 및 인터페이스 필드가 먼저 초기화된다는 점에 유의하세요).

포인트 3에 대한 구체적인 질문이 무엇인지 모르겠습니다 (중첩 된 것을 의미한다고 가정할까요?). 자세한 시퀀스는 이것이 재귀 초기화 요청이므로 초기화를 계속할 것이라고 설명합니다.


정적 필드는 클래스 로더가 클래스를로드 할 때 초기화됩니다. 이때 기본값이 지정됩니다. 이것은 소스 코드에 나타나는 순서대로 수행됩니다.


초기화 순서는 다음과 같습니다.

  1. 정적 초기화 블록
  2. 인스턴스 초기화 블록
  3. 생성자

The details of the process are explained in the JVM specification document.


static variable

  • It is a variable which belongs to the class and not to object(instance)
  • Static variables are initialized only once , at the start of the execution(when the Classloader load the class for the first time) .
  • These variables will be initialized first, before the initialization of any instance variables
  • A single copy to be shared by all instances of the class
  • A static variable can be accessed directly by the class name and doesn’t need any object

Starting with the code from the other question:

class MyClass {
  private static MyClass myClass = new MyClass();
  private static final Object obj = new Object();
  public MyClass() {
    System.out.println(obj); // will print null once
  }
}

A reference to this class will start initialization. First, the class will be marked as initialized. Then the first static field will be initialized with a new instance of MyClass(). Note that myClass is immediately given a reference to a blank MyClass instance. The space is there, but all values are null. The constructor is now executed and prints obj, which is null.

Now back to initializing the class: obj is made a reference to a new real object, and we're done.

If this was set off by a statement like: MyClass mc = new MyClass(); space for a new MyClass instance is again allocated (and the reference placed in mc). The constructor is again executed and again prints obj, which now is not null.

The real trick here is that when you use new, as in WhatEverItIs weii = new WhatEverItIs( p1, p2 ); weii is immediately given a reference to a bit of nulled memory. The JVM will then go on to initialize values and run the constructor. But if you somehow reference weii before it does so--by referencing it from another thread or or by referencing from the class initialization, for instance--you are looking at a class instance filled with null values.


The static variable can be intialize in the following three ways as follow choose any one you like

  1. you can intialize it at the time of declaration
  2. or you can do by making static block eg:

    static {
            // whatever code is needed for initialization goes here
        }
    
  3. There is an alternative to static blocks — you can write a private static method

    class name {
        public static varType myVar = initializeVar();
    
        private static varType initializeVar() {
            // initialization code goes here
        }
    }
    

참고URL : https://stackoverflow.com/questions/8704423/when-are-static-variables-initialized

반응형