이 코드가 있습니다.
package tests;
import java.util.Hashtable;
public class Tests {
public static void main(String[] args) {
Hashtable<String, Boolean> modifiedItems = new Hashtable<String, Boolean>();
System.out.println("TEST 1");
System.out.println(modifiedItems.get("item1")); // Prints null
System.out.println("TEST 2");
System.out.println(modifiedItems.get("item1") == null); // Prints true
System.out.println("TEST 3");
System.out.println(Boolean.valueOf(null)); // Prints false
System.out.println("TEST 4");
System.out.println(Boolean.valueOf(modifiedItems.get("item1"))); // Produces NullPointerException
System.out.println("FINISHED!"); // Never executed
}
}
내 문제는 내가 왜 이해하지 못하는 것입니다 테스트 (3)가 잘 작동 (가 인쇄 false
및 생산하지 않는 NullPointerException
사이에) 시험 4 발생합니다 NullPointerException
. 당신은 테스트에서 볼 수 있듯이 1 과 2 , null
그리고 modifiedItems.get("item1")
동등하고 있습니다 null
.
동작은 Java 7 및 8에서 동일합니다.
답변
어떤 오버로드가 호출되는지주의 깊게 살펴 봐야합니다.
Boolean.valueOf(null)
을 호출하고Boolean.valueOf(String)
있습니다.NPE
null 매개 변수가 제공된 경우에도 는 발생하지 않습니다 .Boolean.valueOf(modifiedItems.get("item1"))
호출되어Boolean.valueOf(boolean)
있기 때문에,modifiedItems
의 값은 타입 인Boolean
개봉기 변환이 필요. 이후modifiedItems.get("item1")
이며null
, 그것은 그 값이다 개봉기 – 아닌Boolean.valueOf(...)
– NPE가 발생한다.
호출되는 오버로드를 결정하는 규칙은 매우 복잡 하지만 대략 다음과 같습니다.
-
첫 번째 패스에서는 boxing / unboxing을 허용하지 않고 메서드 일치를 검색합니다 (변수 arity 메서드도 없음).
- 왜냐하면
null
A에 대한 허용 값은String
아니지만boolean
,Boolean.valueOf(null)
에 매칭Boolean.valueOf(String)
이 패스; Boolean
는Boolean.valueOf(String)
또는에 대해 허용되지Boolean.valueOf(boolean)
않으므로이 패스에서에 대해 일치하는 메서드가 없습니다Boolean.valueOf(modifiedItems.get("item1"))
.
- 왜냐하면
-
두 번째 패스에서 메서드 일치를 검색하여 boxing / unboxing을 허용합니다 (하지만 여전히 가변 arity 메서드는 아님).
- A는
Boolean
로 박싱 될 수boolean
있으므로,Boolean.valueOf(boolean)
에 대한 매칭Boolean.valueOf(modifiedItems.get("item1"))
이 패스; 그러나 unboxing 변환은 그것을 호출하기 위해 컴파일러에 의해 삽입되어야합니다 :Boolean.valueOf(modifiedItems.get("item1").booleanValue())
- A는
-
(가변 arity 메서드를 허용하는 세 번째 패스가 있지만 처음 두 패스가 이러한 경우와 일치하므로 여기서는 관련이 없습니다)
답변
이후 modifiedItems.get
리턴한다 Boolean
(이다 하지 스트 String
)이며, 사용되는 서명 Boolean.valueOf(boolean)
가 Boolean
원시적으로 outboxed됩니다 boolean
. 일단 null
반환 되면 보낼 편지함이 NullPointerException
.
답변
메서드 서명
이 메서드 Boolean.valueOf(...)
에는 두 가지 서명이 있습니다.
public static Boolean valueOf(boolean b)
public static Boolean valueOf(String s)
귀하의 modifiedItems
가치는 Boolean
입니다. 당신은 캐스트 수 없습니다 Boolean
에 String
그래서 결과적으로 최초의 서명이 선택됩니다
부울 언 박싱
당신의 진술에서
Boolean.valueOf(modifiedItems.get("item1"))
다음과 같이 읽을 수 있습니다.
Boolean.valueOf(modifiedItems.get("item1").booleanValue())
그러나 modifiedItems.get("item1")
반환 null
하므로 기본적으로
null.booleanValue()
분명히 NullPointerException
답변
Andy가 이미 그 이유를 잘 설명했듯이 NullPointerException
:
이것은 Boolean un-boxing 때문입니다.
Boolean.valueOf(modifiedItems.get("item1"))
다음으로 변환됩니다.
Boolean.valueOf(modifiedItems.get("item1").booleanValue())
런타임 에 null이면 throw NullPointerException
됩니다 modifiedItems.get("item1")
.
이제 여기에 다음 클래스를 각각의 프리미티브에 NullPointerException
unboxing하면 해당 반환 객체가 null 인 경우 예외가 발생할 수 있다는 점을 한 가지 더 추가하고 싶습니다 .
- 바이트-바이트
- char-문자
- float-부동
- int-정수
- 길다-길다
- 짧음-짧음
- double-더블
다음은 코드입니다.
Hashtable<String, Boolean> modifiedItems1 = new Hashtable<String, Boolean>();
System.out.println(Boolean.valueOf(modifiedItems1.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Byte> modifiedItems2 = new Hashtable<String, Byte>();
System.out.println(Byte.valueOf(modifiedItems2.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Character> modifiedItems3 = new Hashtable<String, Character>();
System.out.println(Character.valueOf(modifiedItems3.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Float> modifiedItems4 = new Hashtable<String, Float>();
System.out.println(Float.valueOf(modifiedItems4.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Integer> modifiedItems5 = new Hashtable<String, Integer>();
System.out.println(Integer.valueOf(modifiedItems5.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Long> modifiedItems6 = new Hashtable<String, Long>();
System.out.println(Long.valueOf(modifiedItems6.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Short> modifiedItems7 = new Hashtable<String, Short>();
System.out.println(Short.valueOf(modifiedItems7.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Double> modifiedItems8 = new Hashtable<String, Double>();
System.out.println(Double.valueOf(modifiedItems8.get("item1")));//Exception in thread "main" java.lang.NullPointerException
답변
그것을 이해하는 방법은 언제 Boolean.valueOf(null)
호출 되는지 , java는 정확하게 null을 평가하도록 지시받는 것입니다.
그러나 Boolean.valueOf(modifiedItems.get("item1"))
가 호출되면 java는 객체 유형 Boolean의 HashTable에서 값을 가져 오도록 지시하지만 Boolean을 예상 했음에도 불구하고 대신 막 다른 골목 (null)을 찾는 Boolean 유형을 찾지 못합니다. NullPointerException 예외는 Java의이 부분의 작성자가이 상황이 프로그래머의주의를 요하는 프로그램에서 잘못되는 인스턴스라고 결정했기 때문에 발생합니다. (의도하지 않은 일이 발생했습니다.)
이 경우 의도적으로 null을 의도했다고 선언하는 것과 객체를 찾으려는 객체 (null)에 대한 누락 된 참조를 찾는 Java의 차이가 더 큽니다.
이 답변에서 NullPointerException에 대한 자세한 정보를 참조하십시오 :
https://stackoverflow.com/a/25721181/4425643