2011-08-09 8 views
6

가능한 복제를 초기화 대 선언에 초기화 : 나는 더 나은 연습과 이유입니다, 궁금 해서요
Should I initialize variable within constructor or outside constructor생성자에

. 선언시 클래스 필드를 초기화해야합니까, 아니면 생성자에서해야합니까? 그것이 한 줄짜리 간단한 초기화라는 점을 감안할 때.

class Dude 
{ 
    String name = "El duderino"; 

    Dude() { 
     // irrelevant code 
    } 
} 

class Dude 
{ 
    String name; 

    Dude() { 
     name = "El duderino"; 

     // irrelevant code 
    } 
} 

편집 : 나는 스타일 중 하나가 예외를 throw 할 수 초기화 코드를 실행의 경우처럼 다른 선호 할 것입니다 상황을 알고 . 여기서 내가 말하는 것은 두 스타일이 절대적으로 동등한 경우입니다. 두 가지 방법 모두 동일한 작업을 수행합니다. 그렇다면 어느 것을 사용해야합니까?

답변

4

경우, 회원 수 접근자를 통해 설정해야합니다 ("setter"메서드), 나는 첫 번째 스타일을 선호합니다. 초기 값은 생성시 기본값이라는 힌트를 제공합니다.

구성 중에 멤버를 지정할 수 있으면 일반적으로 더 적은 수의 매개 변수로 생성자의 적절한 생성자에 기본값을 전달합니다. 예를 들어,

final class Dude { 

    private final String name; 

    Dude() { 
    this("El Duderino"); 
    } 

    Dude(String name) { 
    this.name = name; 
    } 

} 
+0

이것은 합리적으로 들립니다. 하지만 내가 말한 것은 어느쪽으로 든 초기화 될 필드들, 즉 생성자에서 검색된 데이터는 사용되지 않을 것이라는 점입니다. 하위 요소를 저장하기위한 빈 내부 List를 초기화하는 것과 같습니다. 여전히 생성자에서 초기화할까요? – amrhassan

+0

@amrhassan -이 경우, 선언 할 때 초기화하지 않고 '최종'이라고 선언합니다. – erickson

+0

당신의 예제에서'final'을 만들 이유를 알 수 있습니다 만, setter'setName (String name)'이 있다면 ... – knownasilya

0

첫 번째 변수는 일반적으로 정적 변수를 초기화하는 데 사용되며 그 목적으로 만 사용해야합니다.

두 번째 방법을 사용해야합니다.

내가 잘못하면 저를 교정하십시오.

+0

첫 번째 정적 필드는 아무 문제가 없습니다. 그것은 제 2의 종합 설탕입니다. – amit

+0

네가 무슨 뜻인지 알 겠어. 그러나 C++을 사용했다면, 정적 변수를 초기화하기 위해 그가했던 것과 같은 것이 없다는 것을 알게 될 것입니다. 이것은 정적 변수를 초기화하는이 정확한 목적을 위해 java에 추가되었습니다. 따라서, 그것은 그것을 위해 만들어진 목적으로 사용해야합니다. – mtahmed

+0

정적 변수에 대한 첫 번째 스타일을 예약 할 이유가 없습니다. 어떤 추론을 할 수 있습니까? – erickson

0

일관성을 위해 생성자 내에 변수를 선언하는 것이 가장 좋습니다. 변수는 그것을 초기화하기 위해 루프 나 if-else 문과 같은 것을 필요로 할 수 있습니다. 이것은 선언문 안에 연산을 넣지 않고는 할 수 없습니다.

이 규칙의 예외는 정적 변수이며, 생성자 외부에서 선언해야합니다.

+0

초기화 블록을 사용하여 메소드 또는 생성자 내에서만 초기화되는 필드를 초기화 할 수 있습니다. – emory

0

단일 행 선언에는 복잡한 초기화 논리를 포함 할 수 없습니다. 당신은 당신이 한 줄의 초기 값을 제공 할 수 있음을 확인할 수 있습니다

class AnotherClass 
{ 
    MyClass anObject = new MyClass(); //MyClass() throws a checked exception. 
} 

: 당신은 같은 변수를 초기화하는 경우

. 당신은 아주 분명 생성자 내부에가는 것을, 블록에 같은 코드를 삽입해야합니다 (또는 비 정적 초기화 블록) 것이다하십시오 초기화 블록을 사용

class AnotherClass 
{ 
    MyClass anObject; 

    AnotherClass() 
    { 
     try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/} 
    } 
} 

:

생성자를 사용 :

class AnotherClass 
{ 
    MyClass anObject; 

    { 
     try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/} 
    } 
} 

난 후자는 서로 분리 선언 및 초기화로서, 이하 이해할 코드를 만드는 것을 발견하고, 실행시에 아무런 차이가 없다하더라도 초기화 (개발자가 코딩 생성자 발생하지 않는다).

필드 초기화에 관련된 다른 복잡한 루틴도 마찬가지입니다.당신이하려는 경우 예를 들어, Array 또는 Collection을 초기화하고 일부 기본 값으로 배열/콜렉션의 내용을 설정하기 위해, 당신은 생성자 내부에서 그렇게해야합니다

class AnotherClass 
{ 
    Integer[] integers; 

    AnotherClass() 
    { 
     this.integers = new Integer[10]; 
     for(Integer integer: integers) 
     { 
      integer = Integer.MIN_VALUE; 
     } 
    } 
} 
+1

사실 여기에서도 이니셜 라이저 블록을 사용할 수 있기 때문에 생성자가이 경우에도 유일한 방법은 아닙니다 – Voo

+0

예, 너무 혼란 스러울 수도 있습니다. 그러나 그것은 제 의견입니다. 편집 할 것입니다. –

관련 문제