int num = Integer.getInteger (“123”)에서 NullPointerException이 발생하는 이유는 무엇입니까?


106

다음 코드는 다음을 던집니다 NullPointerException.

int num = Integer.getInteger("123");

내 컴파일러 getInteger가 정적이기 때문에 null을 호출 합니까? 말이 안 돼!

무슨 일이야?


3
대신 Integer.getValue ()를 사용하십시오. 이 블로그 게시물 왜 좋은의 explaination입니다 konigsberg.blogspot.in/2008/04/...
Pranaysharma

답변:


212

큰 그림

여기에는 두 가지 문제가 있습니다.

  • Integer getInteger(String) 당신이 생각하는대로하지 않는다
    • null이 경우 반환
  • Integerto 에서 할당 int하면 자동 언 박싱 이 발생합니다.
    • 때문에 IntegerIS null, NullPointerException발생합니다

구문 분석하기 (String) "123"위해 (int) 123, 당신은 예를 사용할 수 있습니다 int Integer.parseInt(String).

참고 문헌

Integer API 참조


의 위에 Integer.getInteger

이 메서드가 수행하는 작업에 대한 설명서의 내용은 다음과 같습니다.

public static Integer getInteger(String nm): 지정된 이름을 가진 시스템 속성의 정수 값을 결정합니다. 지정된 이름의 속성이 없거나 지정된 이름이 비어 있거나 null또는 속성에 올바른 숫자 형식이없는 경우 null반환됩니다.

즉,이 메서드는 a Stringint/Integer값 으로 구문 분석하는 것과 관련이 없지만 오히려 System.getProperty메서드 와 관련이 있습니다.

물론 이것은 상당히 놀라운 일입니다. 라이브러리에 이와 같은 놀라움이 있다는 것은 안타깝지만 귀중한 교훈을 제공합니다. 항상 문서를 찾아 메서드가 수행하는 작업을 확인하십시오.

공교롭게도이 문제의 변형은 Return of the Puzzlers : Schlock and Awe (TS-5186) , Josh Bloch 및 Neal Gafter의 2009 JavaOne 기술 세션 프레젠테이션에 등장했습니다. 결론 슬라이드는 다음과 같습니다.

도덕

  • 도서관에는 이상하고 끔찍한 방법이 숨어 있습니다.
    • 일부는 무해한 이름을 가지고 있습니다.
  • 코드가 잘못 작동하는 경우
    • 올바른 메서드를 호출하고 있는지 확인
    • 라이브러리 문서 읽기
  • API 디자이너 용
    • 최소 경악의 원칙을 위반하지 마십시오
    • 추상화 계층을 위반하지 마십시오
    • 매우 다른 행동에 유사한 이름을 사용하지 마십시오.

완전성을 위해 Integer.getInteger다음 과 유사한 방법도 있습니다 .

관련 질문


자동 언 박싱

물론 다른 문제는 어떻게 NullPointerException던져 지는가입니다. 이 문제에 집중하기 위해 다음과 같이 코드 조각을 단순화 할 수 있습니다.

Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!

다음은 Effective Java 2nd Edition, 항목 49의 인용문입니다. 박스형 기본 형식보다 기본 형식을 선호합니다.

요약하면, 선택권이있을 때마다 boxed primitive보다 우선적으로 primitive를 사용하십시오. 기본 유형은 더 간단하고 빠릅니다. 박스형 프리미티브를 사용해야한다면 조심하세요! Autoboxing은 boxed primitives를 사용하는 위험은 아니지만 자세한 정도를 줄입니다. 프로그램이 두 개의 박스형 프리미티브를 ==연산자 와 비교할 때 ID 비교를 수행합니다. 이는 거의 확실히 원하는 것이 아닙니다. 프로그램이 boxed 및 unboxed 프리미티브와 관련된 혼합 유형 계산을 수행하면 unboxing을 수행하고 프로그램에서 unboxing을 수행하면 NullPointerException. 마지막으로, 프로그램이 기본 값을 상자에 넣으면 비용이 많이 들고 불필요한 객체 생성이 발생할 수 있습니다.

제네릭과 같은 boxed primitive를 사용하는 것 외에 선택의 여지가없는 곳이 있습니다. 그렇지 않으면 boxed primitives를 사용하기로 한 결정이 정당한지 진지하게 고려해야합니다.

관련 질문


11
그래서 Integer.getInteger(s)대략 같 Integer.parseInt(System.getProperty(s))습니까? 시스템 속성에서 정보를 가져오고 있다는 사실을 강조하기 때문에 더 장황하지만 두 번째를 선호한다고 생각합니다.
MatrixFrog

5
그 댓글을 게시하자마자 Integer 클래스의 실제 소스를 볼 수 있다는 것을 깨달았습니다! 나는 Integer.decode대신에를 사용 하는 것을 제외하고는 올바른 길을 가고 있었는데 Integer.parseInt, 이는 각각 선행을 0x찾거나 0숫자를 16 진수 또는 8 진수로 구문 분석합니다.
MatrixFrog

NullPointerException 묻는 사람들을 위해 ? : programmers.stackexchange.com/questions/158908/...
ROMANIA_engineer

2
@Oracle은 java.lang.Integer.getInteger (String)를 더 이상 사용하지 않을 수 있습니까?
mjaggard


6

getInteger () 메소드의 문서를 확인하십시오 . 이 메서드에서 String매개 변수는 지정된 이름을 가진 시스템 속성의 정수 값을 결정하는 시스템 속성입니다. 여기에 설명 된대로 "123"은 시스템 속성의 이름이 아닙니다 . 이 문자열을로 변환 int하려면 메서드를 int num = Integer.parseInt("123").

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.