2013-02-25 7 views
5

중학교 Java 개발자를위한 과제로 제공되는 코드가 있습니다. 나는 5 년 동안 자바를 사용하여이 코드 조각은 날 완전히 혼란 :Java : 객체의 초기화 순서

Hello World! 
variable value = null 

을하지만 우리는 String variable = null;String variable;로 변경하는 경우 우리가해야합니다 :

public class Main { 

    String variable; 

    public static void main(String[] args) { 
     System.out.println("Hello World!"); 
     B b = new B(); 
    } 

    public Main(){ 
     printVariable(); 
    } 

    protected void printVariable(){ 
     variable = "variable is initialized in Main Class"; 
    } 
} 

public class B extends Main { 

    String variable = null; 

    public B(){ 
     System.out.println("variable value = " + variable); 
    } 

    protected void printVariable(){ 
     variable = "variable is initialized in B Class"; 
    } 
} 

가 출력 될 것

Hello World! 
variable value = variable is initialized in B Class 

두 번째 출력이 더 명확합니다. 그래서, 지금까지의 내가 이런 자바 inizialisation의 순서 알고 : 우리는이 루트 상위 클래스에 올 때

  • 우리는 (자바 항상 클래스 객체이다) 클래스 계층 구조의 루트로 이동합니다, :
    • 모든 정적 데이터 필드가 초기화됩니다.
    • 모든 정적 필드 초기화 프로그램과 정적 초기화 블록이 실행됩니다.
    • 모든 비 정적 데이터 필드가 초기화됩니다.
    • 모든 비 정적 필드 초기화 프로그램과 비 정적 초기화 블록이 실행됩니다.
    • 기본 생성자가 실행됩니다.
  • 그런 다음 기본 하위 클래스에 대한 절차를 반복합니다.

    1. : 위의 규칙에 따라

      Calling base class overridden function from base class method, 나는이 같은 순서를 가지고 가정 -

또한 슈퍼 클래스의 맥락에서 this 키워드의 동작을 설명 포스트가 B 클래스의 새 인스턴스를 만듭니다.

  • 부품 클래스 Main으로갑니다.
  • null이있는 main.variable을 초기화합니다.
  • 그러면 Main 클래스의 기본 생성자로 이동합니다.
  • 생성자는 클래스의 Main 메서드를 호출합니다. (? 왜 우리는 여기 this 키워드가없는 main.printvariable를 호출하지 않습니다.)
  • 필드를 b.variable
  • 이제 우리는 클래스 B에 돌아와 "변수가는 B 클래스의 초기화";
  • null 값을 사용하여 필드 b.variable을 초기화해야합니까?
  • 클래스 B의 기본 생성자는 사람이 상속 inizialisation 시퀀스가 ​​작동하는 방법의 완전하고 자세한 설명을 제공 할 수 있습니다,

    하십시오

  • 을 실행.그리고 String variable = null;String variable;으로 변경하면 또 다른 결과가 나타납니다.

    +1

    printVariable을 (고용하지가 있다면 무슨 일이 일어날 지 요청할 수 있습니다) – Jimmt

    +1

    5 년 동안 Java를 작성해 왔으며 디버거 사용법을 모르십니까? (코드를 단계별로 실행하면 어떤 일이 일어나고 어떤 순서로 진행되는지 정확하게 알 수 있습니다.) –

    +0

    @BrianRoach 물론 디버거를 사용할 수 있으며 javap -v -c B.class도 시도했습니다. 그러나 자바 개발자 또는 인터뷰 질문에 대한 이러한 작업을 볼 때마다 출력을 예측하고 이해합니다. 왜 이렇게 작동하며 코드를 약간 수정하면 어떻게됩니까? 단계별 실행은 규칙 및 실행 프로세스의 이유를 설명하지 않습니다. – INlHELL

    답변

    8

    순서는 다음과 같습니다

    1. 홈페이지 -> "안녕하세요"
    2. 홈페이지 -> new() -> b.printVariable() -> 변수를 설정합니다.
    3. initialisi로 돌아 가기 ng B이므로 변수 = null이 발생합니다.

    그래서 기본적으로 슈퍼 객체 Main()은 B 클래스의 초기화 이벤트보다 먼저 생성됩니다. 즉, 나중에 variable = null이 발생합니다. 그렇지 않으면 B가 Main의 초기화를 깨뜨릴 수 있기 때문에 이것은 의미가 있습니다.

    Joshua Bloch는 위험한 상속이 올바른지에 대한 그의 효과적인 자바 서적에서 많은 좋은 근거를 다루고 있습니다. 나는 그것을 권하고 싶습니다.

    +0

    설명을 주셔서 대단히 감사합니다. 또한 언급 한 책에 대해 감사드립니다. 한 번 더 자세히 읽어 보겠습니다. – INlHELL

    2

    먼저, variable = null;을 작성하면 어떻게되는지 이해해야합니다. 해당 코드가 언제 실행됩니까? 이것은 기본적으로 출력을 결정합니다.

    시작하기 전에 class B의 개체를 만들 때 기본 클래스의 printVariable() 함수가 호출되지 않는다는 것을 언급해야합니다. 대신 B의 printVariable()이 항상 호출됩니다.

    variable = null을 사용하면 B의 생성자에 대한 실행이 시작됩니다. 먼저 Main()이 호출되며 printVariable() 메서드가 호출됩니다. 마침내 variable=nullvariable 변수를 덮어 씁니다.

    variable=null을 초기화하지 않은 경우 printVariable() 함수로 설정된 variable은 덮어 쓰지 않으므로 예상 한 결과를 얻을 수 있습니다. 당신이 할 때 요약

    ,이, 문장의 실행 순서입니다 new B() :

    Main()  //super constructor 
        B#printVariable() 
        initializtion of variables in B's constructor (if any) [i.e. variable=null, if present] 
    
    +0

    대단히 감사합니다.이 코드를 완전히 설명해주십시오. 내가 얻지 못했던 방식으로 필드를 초기화 할 수 있습니다. super_class-> method_of_child_class-> field_of_child_class 이 필드는 하위 필드의 초기화 중 필드가 null이 아닌 경우 덮어 쓸 수 있습니다. 수업. – INlHELL

    1

    이것은 좋은 운동입니다! 그러나 중학교 개발자에게 질문하는 것은 공정한 질문이 아닙니다. 이것은 노인을위한 것입니다. 사람이 무슨 일이 일어날 지 응답 할 경우, 인수를 제거하고 원래의 질문을

    public Main(String something){ 
    printVariable(); 
    } 
    

    :하지만 기술적 인 인터뷰하는 동안 유용이 텍스트를 만들기 위해, 나는 메인의 생성자에 인수를 추가하여 수정했던 . 그 사람이 대답을하지 않을 경우 - 계속할 필요가 없습니다 - 중학생입니다. 은 SetVariable처럼 더해야한다 (-

    또한 매우 잘못된 방법 이름입니다) 클래스 B의 보호 규정을 제거하고 골이 사람 :