2009-10-13 10 views

답변

54

question about this very recently for C# ... 거기에 답을 읽으십시오. 기본적으로 똑같습니다. 당신은 또한 Eric Lippert's recent blog post 재미있는 찾을 수 있습니다; 다소 다른 추력을 가지고 있더라도 적어도 같은 지역에 있습니다.

기본적으로 읽을 때까지 변수에 값을 할당해야한다는 것은 좋은 일입니다. 그것은 의도하지 않은 것을 우연히 읽지 않을 것임을 의미합니다. 예, 변수에 기본값이있을 수 있습니다. 그러나 컴파일러가 버그를 대신 잡을 수있는 것은 아닙니다. 아직 할당되지 않은 것을 읽으 려한다는 것을 증명할 수 있다면? 지역 변수에 기본값을 부여하려면 항상 명시 적으로 할당 할 수 있습니다.

로컬 변수는 괜찮습니다. 예를 들어 정적 변수의 경우 컴파일러는 메서드가 호출되는 순서를 알 수 없습니다. "getter"전에 속성 "setter"가 호출됩니까? 알 수있는 방법이 없으므로 위험에 대해 경고하는 방법이 없습니다. 그렇기 때문에 기본 값 은 인스턴스/정적 변수에 사용되는입니다. 적어도 "당시 메모리에 있었던 모든 것"대신에 알려진 값 (0, false, null 등)을 얻습니다. 명시 적으로 지워지지 않은 민감한 데이터를 읽는 잠재적 인 보안 문제도 제거합니다.

+0

객체가 null 인 경우 왜 null로 할당해야합니까? 나는 자바 언어 사람들이이 경우 명백하게하는 것이 더 좋다고 결정한 것으로 생각하지만, 동의하는지 확신 할 수 없다. –

+5

개체가 null이 아닙니다. A * 변수 *는 null 일 수 있지만 객체는 사용할 수 없습니다. 그리고 지역 변수 *는 기본값을 가지지 않습니다. 왜냐하면, 하나도 가지고 있지 않다면, 읽기 전에 반드시 유용한 값을 주어야한다는 것을 의미하기 때문입니다. 그 값을 null로 만들고 싶다면 그건 괜찮아요 ...하지만 컴파일러가 제게 초기화되지 않았을만한 것을 읽으려고하는지 알려주는 것을 좋아합니다 ... –

+0

@Jon "그것도 명시 적으로 삭제되지 않은 민감한 데이터를 읽을 때 잠재적 인 보안 문제가 제거됩니다. " ? 조금 설명해 주시겠습니까? – Geek

1

로컬 변수 및 프리미티브는 값에서 기대하는 바를 알기 때문에 사용하기 전에 초기화해야합니다. 역사적으로 새로운 변수가 생성되면 메모리의 임의의 값을 포함하게됩니다 [그리고 값을 예측할 수 없습니다]. 고아 변수의 존재를 방지하기 때문에 Java도이를 필요로합니다.

0

실제로는 모든 변수를 사용하기 전에 초기화해야합니다.

값을 설정하기 전에 변수를 사용하고 싶을 때는 생각할 수 없습니다 (null과 비교하지 않는 한).

7

로컬 변수의 경우 선언 (메서드에서)과 참조 사이의 프로그램 흐름이 순차적이기 때문에 '전에'의미하는 것이 명확합니다. 메소드 외부에서 선언 된 필드의 경우 컴파일러는 어떤 코드가 사용될 것인지 결코 알지 못하기 때문에 다른 메소드가 필드를 초기화하기 전에 오류를 생성 할 수 없습니다.

+0

+1 "선언 (메소드에서)과 참조 사이의 프로그램 흐름은 순차적입니다." – luigi7up

3

완전히 사실은 아닙니다. 로컬 변수는 참조 인 경우에만 초기화해야합니다. 참조되지 않으면 로컬 변수를 초기화하지 않은 상태로 둘 수 있습니다. 예를 들어,

6

Java에서 클래스 및 인스턴스 변수는 수동으로 초기화하지 않으면 기본값 (null, 0, false)으로 간주됩니다. 그러나 지역 변수에는 기본값이 없습니다. 지역 변수에 값이 할당되어 있지 않으면 컴파일러는이를 읽는 코드를 컴파일하지 않습니다. IMHO, 결론적으로 말하자면, 지역 변수를 선언 할 때 (null과 같은) NullPointerException으로 이어질 수있는 지역 변수를 초기화하는 것은 실제로 나쁜 일입니다. 다음의 예를 생각해

Object o; 
if (<some boolean condition>) 
    o = <some value>; 
else 
    o = <some other value>; 
System.out.println(o); 

널 (null)와 o의 초기화 코드 경로 이전 (null 또는 일부 null 이외의 값 중 하나와 함께) o 초기화 것을, 컴파일시에 자바 컴파일러를 확인하기 때문에, 완전히 불필요 변수가 읽 t집니다.즉 위의 코드 조각에서 변수 o의 두 초기화 중 하나를 주석으로 처리하려면 컴파일러에서 라인 System.out.println(o);을 컴파일하는 것을 거부합니다.

이것은 Java와 Java에서만 가능합니다. 나는 C#과 같은 언어에 대해서 모른다. 그러나 좋은 오래된 C (그리고 어쩌면 C++)에서는 AFAIK 선언시 항상 변수를 초기화하는 것이 좋습니다. 그러한 "오래된 학교"프로그래밍 언어는 변수가 항상 초기화되었는지 여부를 추적하는 Java와 같은 현대 언어에 대한 책과 토론에서 항상 변수를 초기화하라는 권장 사항이 나오는 이유 일 수 있습니다.

+0

"구식"언어는 값을 입력해야만 변수를 선언 할 것을 권장합니다. :-) –

+0

위의 예를 고려하십시오. 값이 복잡한 if 문의 결과에 따라 달라지는 경우 어떻게 변수에 넣을 값을 가질 수 있습니까? IMHO, 당신이 제안하는 규칙은 큰 문제가 있습니다. – Sven

+0

값에 복잡한 연산이 필요한 경우이를 별도의 함수에 넣고 함수 호출을 이니셜 라이저로 사용할 수 있습니다. –

관련 문제