[java] String.valueOf (null)이 NullPointerException을 발생시키는 이유는 무엇입니까?

설명서에 따르면이 메서드 String.valueOf(Object obj)는 다음을 반환합니다.

인수가이면 null문자열과 "null"; 그렇지 않으면의 값 obj.toString()이 반환됩니다.

그러나 이것을 시도 할 때 어떻게됩니까?

System.out.println("String.valueOf(null) = " + String.valueOf(null));

대신 NPE를 던지나요? (믿지 않으면 직접 시도하십시오!)

    스레드 "main"의 예외 java.lang.NullPointerException
    java.lang.String. (알 수없는 소스)
    java.lang.String.valueOf (알 수없는 소스)

어떻게 이런 일이 일어나고 있습니까? 문서가 나에게 거짓말입니까? Java의 주요 버그입니까?



답변

문제는 String.valueOf메소드가 오버로드 된다는 것입니다 .

Java Specification Language는 이러한 종류의 경우 가장 구체적인 과부하 가 선택되도록 요구합니다.

JLS 15.12.2.5 가장 구체적인 방법 선택

둘 이상의 멤버 메소드가 액세스 가능하고 메소드 호출에 적용 가능한 경우, 런타임 메소드 디스패치에 대한 설명자를 제공 할 멤버를 선택해야합니다. Java 프로그래밍 언어는 가장 구체적인 방법을 선택 한다는 규칙을 사용합니다 .

A는 char[] -입니다 Object ,하지만 모든 Object 입니다-A char[] . 따라서, char[]더 구체적인 것보다 Object, 그리고 자바 언어에 의해 지정된대로 String.valueOf(char[])과부하이 경우 선택됩니다.

String.valueOf(char[])는 배열이 아닌 것으로 예상하고 null, null이 경우 주어진 이후에을 던진다 NullPointerException.

쉬운 “수정”은 다음과 같이 null명시 적으로 캐스팅하는 Object것입니다.

System.out.println(String.valueOf((Object) null));
// prints "null"

관련 질문


이야기의 교훈

몇 가지 중요한 것들이 있습니다.

  • 효과적인 Java 2 판, 항목 41 : 신중하게 과부하 사용
    • 과부하가 걸린다고해서 항상 매번해야하는 것은 아닙니다
    • 혼란을 일으킬 수 있습니다 (특히 방법이 크게 다른 경우)
  • 좋은 IDE를 사용하면 컴파일 타임에 어떤 과부하가 선택되었는지 확인할 수 있습니다
    • 이클립스를 사용하면 위의 발현에 마우스 호버를 할 수 있고 볼 valueOf(char[])과부하를 선택!
  • 때로는 명시 적으로 캐스팅하고 싶을 때가 있습니다 null(예제)

또한보십시오


캐스팅시 null

null특정 참조 유형 으로 명시 적으로 캐스트해야하는 두 가지 상황 이 있습니다.

  • 과부하를 선택하려면 (위의 예에서와 같이)
  • nullvararg 매개 변수에 단일 인수로 제공하려면

후자의 간단한 예는 다음과 같습니다.

static void vararg(Object... os) {
    System.out.println(os.length);
}

그러면 다음을 가질 수 있습니다.

vararg(null, null, null); // prints "3"
vararg(null, null);       // prints "2"
vararg(null);             // throws NullPointerException!

vararg((Object) null);    // prints "1"

또한보십시오

관련 질문


답변

문제는 당신이 전화하고 있다는 것입니다 String.valueOf(char[])없습니다 String.valueOf(Object) .

그 이유는 Java가 항상 제공된 매개 변수와 작동하는 가장 특정한 오버로드 된 메소드 버전을 선택하기 때문입니다. 매개 변수 null의 유효한 값 Object이지만 매개 변수의 유효한 값이기도합니다 char[].

Java가 Object버전을 사용하게하려면 null변수 를 통해 전달 하거나 Object에 명시 적 캐스트를 지정하십시오.

Object o = null;
System.out.println("String.valueOf(null) = " + String.valueOf(o));
// or
System.out.println("String.valueOf(null) = " + String.valueOf((Object) null));


답변

4867608 로 번호가 매겨진 버그 는 2003 년에이 방법으로 제출 되었으며이 설명과 함께 “수정되지 않음”으로 해결되었습니다.

호환성 제약으로 인해이를 변경할 수 없습니다. 이 메소드는 호출되는 최종 정적 String valueOf (char data []) 메소드이며 널 (null) 인수에 대한 “널 (null)”대체를 언급하지 않습니다.

@ ###. ### 2003-05-23


답변

String.valueOf(null: Any)스칼라에서 사용하십시오 .


답변