2009-07-25 5 views
5

관찰자 ArrayList를 초기화하는 두 가지 방법의 차이점은 무엇입니까? 또는 그 유형에 대한 다른 유형. 하나가 다른 것보다 빠릅니까? 아니면 다른 혜택을 놓치고 있습니다.Java : 이러한 구성 방법의 차이점은 무엇입니까

class Publisher implements Observerable 
{ 
    private ArrayList observers = new ArrayList(); 
} 

class Publisher implements Observerable 
{ 
    private ArrayList observers; 

    public Publisher() 
    { 
     observers = new ArrayList(); 
    } 
} 

답변

13

등가입니다. 당신이 두 가지를 컴파일하는 경우 사실, 당신은 그들이 정확히 같은 바이트 코드를 생성 것을 볼 수 있습니다 :

Publisher(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: aload_0 
    5: new  #2; //class java/util/ArrayList 
    8: dup 
    9: invokespecial #3; //Method java/util/ArrayList."<init>":()V 
    12: putfield  #4; //Field observers:Ljava/util/ArrayList; 
    15: return  
} 

가 동일한 코드를 걸 감안를 명확하게 어떤 속도 차이 :

이 될 수 없다

C#에서는 그다지 동일하지 않습니다. C#에서는 observers의 이니셜 라이저가 기본 생성자 호출 인 전에 을 실행합니다. Java에서는 실제로 동일합니다.

당신이 사용하는 것은 취향입니다. 같은 방법으로 변수를 모두 초기화하는 여러 생성자가있는 경우 첫 번째 형식을 사용하는 것이 좋습니다. 다른 한편, 실제 작업을 수행하는 "핵심"생성자를 대부분 호출하도록하려는 여러 생성자가있는 경우 일반적으로 좋은 아이디어입니다.

+1

존 소총의 편집은 또한 인스턴스의 초기화와 같은 바이트 코드를받을 수 있나요 다시 –

+1

공격 다음과 같이

public static void main(String[] args) { new TestSub("super constructor"); } 

결과는? 대답은 '예'라고 생각합니다. –

+1

@ mmyers : 네, 정확히 똑같습니다. –

4

그들은 동일하지만 : 어떤 차이가 진짜가 아니다 오류 등

1

처리 : 의 차이는 마지막 예를 들어, 당신은 고급 초기화 로직을 수행 할 수있는 이점을 얻을 수 있다는 것입니다. 첫 번째 방법의 장점은 여러 생성자가있는 경우 모두에서 observers을 초기화하는 것을 기억할 필요가 없다는 것입니다.

두 번째 예에서는 생성자의 인수를 기반으로 값을 조정하려는 경우보다 유연하게 작업 할 수 있습니다.

2

유일한 차이점은 작업 순서입니다. 선언에서 초기화되는 필드는 클래스 생성자가 호출되기 전에 평가됩니다. 이 방법으로 서브 클래스에서 초기화되는 필드는 슈퍼 생성자가 완료된 후 서브 클래스의 생성자가 호출되기 전에 평가됩니다.

public class Tester { 
    Tester (String msg) { 
     System.out.println(this + ":" + msg); 

    } 
} 

내가 수퍼 클래스가 :

public class Test { 

    protected Tester t1 = new Tester("super init block"); 

    Test (String constructorMsg) { 
    new Tester(constructorMsg); 
    } 
} 

을 내가 서브 클래스가 있습니다

Public class TestSub extends Test { 

    private Tester t2 = new Tester("sub init block"); 

    TestSub(String constructorMsg) { 
     super(constructorMsg); 
     new TTester("sub constructor"); 
    } 

} 
을 내가 테스트 클래스가

:

는 다음과 같은 예를 생각해

내 01 있음 2,방법, 나는 TestSub의 인스턴스를 생성 :

[email protected]:super init block 
[email protected]:super constructor 
[email protected]:sub init block 
[email protected]:sub constructor 
+0

두 번째 버전의 생성자가 첫 번째 버전의 필드 이니셜 라이저와 동일한 호출로 구성되어 있기 때문에 질문에 표시된 예제의 경우 * 차이가 없음을 나타냅니다. 중요하게도, 필드 이니셜 라이저는 이전이 아닌 superconstructor라고 부릅니다. –

관련 문제