2009-12-12 3 views
8
class test 
{ 
    test() 
    { 
     System.out.println("Constructor"); 
    } 

    { 
    System.out.println("Hai"); 
    } 

} 
public class sample 
{ 
    public static void main(String [] a) 
    { 
     test t = new test();   
    } 
} 

위의 코드에서 중괄호 (즉 "Hai") 내에 주어진 문이 인쇄자가 constructor가 실행되기 전에 인쇄되는 이유는 무엇입니까?자바 기본에 의문이 있으십니까?

답변

31

더 명확한 예제를 표현하자 :

public class Test { 

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

    { 
     System.out.println("instance initializer"); 
    } 

    public Test() { 
     System.out.println("constructor"); 
    } 

} 

다음과 같이 테스트 :

public class Main { 

    public static void main(String[] args) { 
     Test test1 = new Test(); 
     Test test2 = new Test(); 
    } 

} 

출력 : 정적 초기화는 한 번 실행됩니다

static initializer 
instance initializer 
constructor 
instance initializer 
constructor 

런타임 동안, 특히 클래스를로드하는 동안 인스턴스 이니셜 라이저는 생성자 이전의 모든 인스턴스화 중에 실행됩니다.

두 개 이상 가질 수 있으며 코딩에 표시된 순서대로 실행됩니다.

인스턴스 이니셜 라이저의 주요 장점은 사용하는 생성자에 관계없이 실행된다는 것입니다. 그것들은 각각에 공통적 인 초기화를 복제 할 필요가 없도록 각각에 적용됩니다.

정적 초기화 프로그램의 주요 이점은 클래스로드 중에 한 번만 실행된다는 것입니다. 잘 알려진 실세계의 예는 JDBC 드라이버입니다. 당신은 단지 static 초기화를 실행

Class.forName("com.example.jdbc.Driver"); 

을 수행 할 때

static { 
     DriverManager.registerDriver(new com.example.jdbc.Driver()); 
} 

이 식으로 DriverManager는 동안 올바른 JDBC 드라이버를 찾을 수를 다음과 같이 다음 어떤 (괜찮은) JDBC 드라이버는 DriverManager에 자신을 등록합니다 getConnection().

5

예. instance initializer입니다. 클래스가 인스턴스화되는 즉시 실행됩니다.

+2

정적 키워드는 선택 사항입니까? – blackanchorage

+0

그래서 위의 코드에서 정적 블록을 만들면 먼저 정적 블록이나 정적 이니셜 라이저 블록이 실행됩니까? ... ... 정적 초기화자를 설명 할 수 있습니까? – Hariharbalaji

+1

확실히 '정적'초기화 프로그램이 아닙니다. – BalusC

2

클래스 내에서 즉시 중괄호에 인스턴스 초기 자 (Java 1.1에서 도입)가 도입되었습니다. 그들은 선언의 일부로 쓰여진 필드를 할당하는 코드와 거의 같은 것으로 취급됩니다. 그래서 다음과 동일합니다

private final Thing x = new Thing(); 

private final Thing x; 
{ 
    x = new Thing(); 
} 

코드는 바로 슈퍼 생성자를 호출 한 후 생성자에 의해 실행된다. 그래서, 다른 초기화 없다고 가정의 코드는 생성자의 일부로서 동등하게 쓸 수있다 :

교정기 한 번 실행 static 키워드 및 정적 initialisers 앞에 같은 위치에서 클래스는,하지에 초기화 될 때
private final Thing x; 
public MyCLass() { 
    super(); // Often implicit. 
    x = new Thing(); 
} 

인스턴스별로

3

위의 코드에서 생성자가 실행되기 전에 중괄호 (즉 "Hai") 내에 제공된 문구가 인쇄되는 이유는 무엇입니까?

이것은 Java Language Specification :)

12.5 Creation of New Class Instances 다만 결과로서 반환 새로 생성 된 객체에 대한 참조 이전 섹션에 설명 된대로 예상되는 동작이기 때문에이 표시된 생성자는

  1. 은 ARG를 할당 : 다음 절차를 사용하여 새로운 객체 를 초기화 처리 새롭게 생성 된 파라미터 이 생성자의 변수에 대한 생성자의 식별자 호출. 이 생성자는 의 명시 적 생성자 호출 (this 사용) 같은 클래스 의 다른 생성자로 시작하는 경우
  2. , 다음 반복적으로이 같은 다섯 단계를 사용하여 호출을 생성자 인수 및 프로세스를 평가합니다. 해당 생성자 호출이 갑자기 완료되면 이 절차는 에 대해 갑자기 완료됩니다. 그렇지 않으면 을 5 단계로 계속 진행하십시오.
  3. 이 생성자는 동일한 클래스 (this 사용)의 에있는 다른 생성자의 명시 적 생성자 호출로 시작하지 않습니다. 이 생성자 Object가 아닌 다른 클래스의 경우,이 생성자는 (super 사용) 슈퍼 클래스 생성자 의 명시 적 또는 암시 호출로 시작됩니다. 인수를 평가하고 이러한 동일한 5 단계를 사용하여 해당 수퍼 클래스 생성자 호출을 재귀 적으로 으로 처리하십시오. 해당 생성자 호출이 갑자기 을 완료하면 이 같은 이유 때문에 갑자기 완료됩니다. 그렇지 좌우 위해, 이 클래스의 인스턴스 이니셜과 인스턴스 변수 초기화를 실행 대응 인스턴스 변수 인스턴스 변수 초기화 값을 할당하는 단계 4.
  4. 계속 그 (것)들은 는 종류를위한 원본 코드 에서 원본으로 보입니다. 이러한 초기화 프로그램을 실행하면 예외가 발생하고 초기화 프로그램이 처리되지 않으며이 프로 시저가 갑자기 완료되고 동일한 예외가 발생합니다. 이 필드를 초기화 필드 초기화 식 치가 의 디폴트 초기 값과 동일했다 일정한 식 이었다면 그렇지 일부 초기 구현 예에서 5 단계로 ( 잘못 코드 생략 컴파일러 계속 그 타입).
  5. 이 생성자의 나머지 부분을 실행한다. 해당 실행 이 갑자기 완료되면 동일한 이유로이 프로 시저가 갑자기 완료됩니다. 그렇지 않으면이 절차 이 정상적으로 완료됩니다.에 ... 인스턴스 초기화 자세한 내용은

항을 참조 8.6 Instance Initializers.