이름없이 Java 메서드 호출


101

아래 코드를보고 약간 이상한 것을 발견했습니다.

public class Sequence {
    Sequence() {
        System.out.print("c ");
    }

    {
        System.out.print("y ");
    }

    public static void main(String[] args) {
        new Sequence().go();
    }

    void go() {
        System.out.print("g ");
    }

    static {
        System.out.print("x ");
    }
}

System.outwith "y"가 메서드 선언에 속하지 않기 때문에 컴파일 오류가 발생할 것으로 예상 했습니다 { }. 이것이 유효한 이유는 무엇입니까? 이 코드가 어떻게 호출되어야하는지 모르겠습니다.

이것을 실행할 x y c g때도 생성됩니다 . 왜 static { }시퀀스 생성자보다 먼저 get이 호출됩니까?

답변:


149

이:

static {
        System.out.print("x ");
    }

A는 정적 초기화 블록 , 그리고 클래스가로드 될 때 호출된다. 원하는만큼 클래스에 포함 할 수 있으며 모양 순서대로 (위에서 아래로) 실행됩니다.

이:

    {
        System.out.print("y ");
    }

초기화 블록 이며 코드는 클래스의 각 생성자 시작 부분에 복사됩니다. 따라서 클래스의 생성자가 많고 모두 처음에 공통된 작업을 수행해야하는 경우 코드를 한 번만 작성하고 이와 같은 초기화 블록 에 넣으면됩니다 .

따라서 출력이 완벽하게 이해됩니다.

Stanley가 아래에 언급 했듯이 자세한 내용은 초기화 블록설명하는 Oracle 자습서의 섹션 을 참조하십시오.


12
좋은 대답입니다. 초기화 블록에 대한 자세한 내용은 http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
Stanley

6
the code is copied into the beginning of each constructor of the class-이것은 올바르지 않습니다. 생성자가로 시작한다고 가정 해 봅시다 super("x ");. 슈퍼 생성자는 초기화 블록보다 먼저 실행됩니다.
RokL

3
예, superconstructor에 대한 암시 적 및 명시 적 호출이 먼저 실행되고 초기화 블록이 다음으로 실행되고 나머지 생성자 코드보다 실행됩니다.
jlordo

25

메소드가 아니라 초기화 블록 입니다.

 {
    System.out.print("y ");
 }

생성자 호출 전에 실행됩니다. 동안

static {
        System.out.print("x ");
       }

정적 초기화 블록 클래스는 클래스 로더에 의해 로딩 될 때 실행된다.

따라서 코드를 실행하면
1. 클래스가 클래스 로더에 의해로드되므로 정적 초기화 블록이 실행됩니다.
Output : x가 인쇄됩니다
. 2. 객체가 생성되어 초기화 블록이 실행되고 생성자가
Output 이라고합니다 . y가 인쇄되고 c
3이 뒤 따릅니다 . 차례로 go 메서드를 호출하는 Main 메서드가 호출됩니다
. 출력 : g가 인쇄됩니다.

최종 출력 : xycg
이 힘의 도움을 http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/


@Cthulhu : 감사합니다. 지난주까지 새 링크로 업데이트했습니다.
xyz

16

그건의 인스턴스 초기화 블록 a로 하였다 정적 초기화 블록 .

{
    System.out.print("y ");
}

클래스의 인스턴스를 만들 때 호출됩니다.

static {
    System.out.print("x ");
}

클래스 로더가 클래스를로드 할 때 호출됩니다. 그래서 당신이 할 때

new Sequence().go();

클래스가로드되어 static {}실행되고 인스턴스 초기화 블록이 실행 {}되고 생성자의 본문이 호출 된 다음 새로 생성 된 인스턴스의 메서드가 호출됩니다. 출력을 Ergo하십시오 x y c g.


15
static {
        System.out.print("x ");
    }

A는 정적 블록 및 클래스 로딩 중이라고합니다

{
    System.out.print("y ");
}

초기화 블록은

한 클래스에 여러 초기화 블록이있을 수 있으며,이 경우 클래스에 나타나는 순서대로 실행됩니다.

클래스에있는 모든 초기화 블록은 생성자보다 먼저 실행됩니다.


10
static {
      System.out.print("x ");
}

클래스가 공유하는 초기화 블록 (으로 static표시됨)으로, 먼저 실행됩니다.

{
        System.out.print("y ");

}

다음에 오는 클래스의 모든 객체 (생성자)가 공유하는 초기화 블록입니다.

Sequence() {
        System.out.print("c ");
}

세 번째로 실행되는 클래스의 특정 생성자입니다. 인스턴스 초기화 블록은 생성자가 실행될 때마다 먼저 호출됩니다. 이것이 "y"가 "c"바로 앞에 오는 이유입니다.

void go() {
        System.out.print("g ");
}

위의 생성자를 사용하여 생성 된 객체와 관련된 인스턴스 메서드 일 뿐이며 마지막에 있습니다.


9
{
    System.out.print("y ");
}

이러한 종류의 블록을 initializer block. 의 인스턴스를 만들 때마다 실행됩니다 class. 컴파일 타임에이 코드는 클래스의 모든 생성자로 이동됩니다.

static initializer블록의 경우 :-

static {
    System.out.println("x ");
}

클래스가로드 될 때 한 번 실행됩니다. 우리는 일반적으로 필드를 static초기화 할 때 static여러 단계가 필요할 때 이니셜 라이저 블록을 사용 합니다.


6

초기화 블록 으로 사용되며 정적 선언 후에 실행됩니다 . Singleton 디자인 패턴에서 와 같이 다른 사람이 클래스의 인스턴스를 만들 수 없도록하는 데 사용할 수 있습니다 (개인 생성자를 사용하는 것과 같은 방식으로) .


3
static {
    System.out.print("x ");
}

Static blocks클래스가 JRE에 의해 로드 되고 초기화 될 때 한 번만 실행됩니다 .

그리고 non-static블록은 새 인스턴스를 만들 때마다 호출 되며 생성자 바로 전에 호출됩니다.

여기에서 생성 된 것처럼 생성 된 인스턴스는 블록 Sequence이후에 호출 된 non-static다음 실제로 목표가되는 메서드 가 1 개만 생성 되었습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.