2013-06-15 5 views
5

참고 : 문제를 해결하면 초기화하는 것이 좋습니다. 필자는 컴파일러가 실행 경로를 따라 가며 foo가 실제로 '그렇지 않을 수도 있음'을 암시하는 지점에서 실제로 초기화된다는 것을 알았습니다.Java 초기화시 예기치 않은 동작이 발생했습니다.

길이가 3을 넘지 않는다면, 메모리를 할당 할 필요가 없다는 것을 처음으로 가정했습니다.

이 생산에 사용되지 않습니다

, 나는

다음 예를 참조하십시오 단순히 호기심 : -

List<String> foo; 

int length = 5; 

if (length > 3) 
{ 
    foo = new ArrayList<String>(); 
} 

if (length > 4) 
{ 
    foo.add("bar"); 
} 

가 왜이 표시하려면 다음을 일으키는?

가 지역 변수 foo는이 확실하게 가지를 다음

초기화되지 않았을 수 있습니다, foo는 초기화되지 않고, 이에 경우가 결코 없다.

List<String> foo = null; 

더 컴파일 문제가 없을 것입니다,하지만 내가 왜이 일을해야합니까 -이 : 난다면 어떻게 알고?

+2

@down 유권자, 적어도 이유를 설명해 주시겠습니까? – chrisw

답변

5

로컬 변수는 기본적으로 초기화되지 않으므로 다른 곳에서 사용하기 전에 초기화해야합니다. if()true이 아닌 경우 어떻게해야합니까?

if (length > 3) 
{ 
    foo = new ArrayList<String>(); 
} 

컴파일러는 조건이 true인지 알 수 없습니다. 이 사용되기 전에

로컬 변수 (§14.4는 §14.13) 명시 적으로 확인 될 수있는 방법 중 초기화 (§14.4) 또는 할당 (§15.26) 하여 값을 부여해야 컴파일 시간 자체 컴파일러가 length의 값은 항상 5 될 것이다 것을 알고 있기 때문에, 컴파일 오류를 해결합니다 lengthfinal로 @jlordo 만드는 지적 명확한 할당

의 규칙을 사용하여 컴파일러 따라서 조건은 length>3입니다. 항상 true이므로 로컬 변수가 초기화됩니다.

+1

+1 이것은 "컴파일러가 확인할 수있는 방식으로"입니다. 컴파일러는 원칙적으로 foo가 여기에 사용되기 전에 항상 할당된다는 것을 알 수 있지만 그렇게하지는 않습니다. –

+0

+1 그 견적은 설명과 함께 오류가 발생한 이유를 확실히 분명히합니다. – chrisw

5

컴파일러는 블록을 입력하면 처음이라는 것을 확신 할 수 없습니다. 그렇지 않은 경우 foo은 초기화되지 않은 상태로 유지됩니다. 초기화되지 않은 변수에 add을 호출 할 수 없습니다. length을 최종 작성하여 컴파일러를 도울 수 있습니다. 그러면 컴파일러는 첫 번째 if 블록이 실행된다는 것을 알게됩니다.

final int length = 5; 
+0

@ oscarLópez : OPs 코드를 복사하고 'length'를 final로 지정하면 컴파일러 오류가 사라집니다.) – jlordo

+1

@Oscar, final은 코드가 오류없이 컴파일되도록합니다. 이것이 옳은 일인지 아닌지는 다른 토론을위한 것입니다. – chrisw

+0

@ chrisw69 : 맞아. 나는 이것이 컴파일러 오류를 제거 할 것이라고 말하고있다. 나는 그것이 좋은 스타일이라고 말하는 것이 아닙니다. – jlordo

1

이는 분기에서 foo가 초기화되어 발생합니다. 따라서 컴파일러는 foo가 초기화되는지 여부를 확신하지 못합니다.

2

로컬 인스턴스가 기본적으로 초기화되지 않으므로 클래스 또는 객체 인스턴스와 다릅니다.Java Language Specification 가입일

:이 사용되기 전에

로컬 변수 (§14.4는 §14.14) 명시하는 방식으로, 하나의 초기화 (§14.4) 또는 할당 (§15.26)에 의해, 값을 부여해야 (16 절)에 대한 규칙을 사용하여 컴파일러에 의해 검증 될 수있다.

기본값 :

For type byte, the default value is zero, that is, the value of (byte)0. 
For type short, the default value is zero, that is, the value of (short)0. 
For type int, the default value is zero, that is, 0. 
For type long, the default value is zero, that is, 0L. 
For type float, the default value is positive zero, that is, 0.0f. 
For type double, the default value is positive zero, that is, 0.0d. 
For type char, the default value is the null character, that is, '\u0000'. 
For type boolean, the default value is false. 
For all reference types (§4.3), the default value is null. 
1

인스턴스와 클래스 변수는 널 (null) 또는 0 값으로 초기화됩니다. 그러나 지역 변수는 그렇지 않습니다. 따라서 로컬 변수를 사용하기 전에 초기화해야합니다.

관련 문제