java에서 null로 타입 캐스팅하는 동안 예외가 없습니다.


227
String x = (String) null;

이 진술에 예외가없는 이유는 무엇입니까?

String x = null;
System.out.println(x);

인쇄합니다 null. 그러나 .toString()메소드는 널 포인터 예외를 발생시켜야합니다.


컴파일러에 대해 어떤 예외가 있습니까?
사잔 찬드 란

답변:


323

당신은 캐스팅 할 수 있습니다 null예외없이 모든 참조 유형으로 할 .

println메서드는 먼저 개체가 null인지 여부를 확인하므로 null 포인터를 throw하지 않습니다. null의 경우는 단순히 캐릭터 라인을 인쇄합니다 "null". 그렇지 않으면 toString해당 객체 의 메소드를 호출 합니다.

세부 사항 추가 : 내부적으로 인쇄 메소드 String.valueOf(object)는 입력 오브젝트에서 메소드를 호출 합니다. 그리고 valueOf메소드 에서이 검사는 null 포인터 예외를 피하는 데 도움이됩니다.

return (obj == null) ? "null" : obj.toString();

혼동을 피하기 위해 특별한 경우가 아니라면 null 객체에서 메소드를 호출하면 null 포인터 예외가 발생합니다.


1
@JunedAhsan 어떤 특별한 경우에 NPE가 발생하지 않습니까?
Holloway

@Trengot 아래 Peter 답변에서 언급 한 답변을 확인하십시오.
Juned Ahsan

144

null모든 참조 유형으로 캐스트 할 수 있습니다 . null예를 들어 인수 를 처리하는 메소드를 호출 할 수도 System.out.println(Object)있지만null 값을 하고 메소드를 호출 .

BTW null값에 정적 메소드를 호출 할 수있는 까다로운 상황이 있습니다 .

Thread t = null;
t.yield(); // Calls static method Thread.yield() so this runs fine.

12
와. 요청을 받으면 예외가 발생할 것이라고 100 % 확신합니다. 참 까다로운 경우입니다.
Magnilex

2
@ Magnilex : 물론입니다! 이것은 전형적인 OCPJP 시험 마술 문제입니다.
ccpizza

3
바이트 코드의 컴파일러가 t.yield() -> Thread.yeld() 어쨌든 "최적화"하기 때문에 그렇지 않습니까? 방법과 유사 final int i = 1; while (i == 1)에 최적화되어 있습니다while(true)
SGal

@SGal 두 번째 최적화는 AFAIK가 필수는 아니지만 첫 번째 최적화는 필수이므로 더 좋습니다.
Paul Stelian

36

이것은 의도적으로 설계된 동작입니다. null모든 참조 유형으로 캐스트 할 수 있습니다 . 그렇지 않으면 참조 변수에 할당 할 수 없습니다.


감사! 참조 변수에 null을 할당하는 것에 관한이 노트가 정말 도움이됩니다!
최대

22

메소드가 오버로드되는 구문을 따르는 데 널 값을 캐스트해야하며 널이 이러한 오버로드 된 메소드에 전달되면 컴파일러는 모호성을 정리하는 방법을 모르므로 다음과 같은 경우 널을 캐스트해야합니다.

class A {
  public void foo(Long l) {
    // do something with l
  }
  public void foo(String s) {
    // do something with s      
  }
}
new A().foo((String)null);
new A().foo((Long)null);

그렇지 않으면 필요한 메소드를 호출 할 수 없습니다.


대부분의 경우 캐스팅은 암시 적입니다. 예를 들어 값을로 String bar = null;캐스팅합니다 . 지금까지 메서드가 오버로드 된 테스트에서 null을 명시 적으로 캐스팅해야했으며 null 입력으로 동작을 테스트하고 싶었습니다. 아직도, 나는 당신을 발견하기 전에 비슷한 대답을 쓰려고했습니다. nullString
Vlasec

재미있는 사실 : l instanceof Longs instanceof String반환 false이러한 경우.
Attila Tanyi

7

Println(Object) 사용 String.valueOf()

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

Print(String) null 확인을 수행합니다.

public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
}

5

여기에 많은 답변이 이미 언급되어 있습니다.

모든 참조 유형에 null을 캐스트 할 수 있습니다.

인수가 널이면 "null"과 같은 문자열

나는 그것이 어디에 지정되어 있는지 궁금해하고 그것을 Java Specification을 찾아 보았다.

null 참조는 항상 모든 참조 유형 (§5.2, §5.3, §5.5)에 할당하거나 캐스트 할 수 있습니다.

참조가 널이면 문자열 "null"(4 개의 ASCII 문자 n, u, l, l)로 변환됩니다.


3

다른 사람들이 작성한 것처럼 모든 것에 널을 던질 수 있습니다. 일반적으로 필요하지 않을 것입니다.

String nullString = null;

거기에 캐스트를 넣지 않고.

그러나 그러한 캐스트가 이해되는 경우가 있습니다.

a) 특정 메소드가 호출되도록하려면 다음과 같이하십시오.

void foo(String bar) {  ... }
void foo(Object bar) {  ... }

입력하면 차이가납니다

foo((String) null) vs. foo(null)

b) IDE를 사용하여 코드를 생성하려는 경우 예를 들어 나는 일반적으로 다음과 같은 단위 테스트를 작성하고 있습니다.

@Test(expected=NullPointerException.class)
public testCtorWithNullWhatever() {
    new MyClassUnderTest((Whatever) null);
}

나는 TDD를하고있다; 이것은 "MyClassUnderTest"클래스가 아직 존재하지 않음을 의미합니다. 해당 코드를 작성하여 IDE를 사용하여 먼저 새 클래스를 생성 할 수 있습니다. 그리고 "What out"인수 "out of the box"를 받아들이는 생성자를 생성하려면 IDE는 테스트에서 생성자가 정확히 Whatever 유형의 인수를 하나만 가져야한다는 것을 알 수 있습니다.


2

인쇄 :

개체를 인쇄하십시오. String.valueOf (Object) 메소드에 의해 생성 된 문자열은 바이트로 변환됩니다.

ValueOf :

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

객체가 일 때 값이 "null"인 문자열을 반환합니다 null.


2

모호한 방법을 사용할 때 매우 유용합니다. 예를 들어, JDialog에는 다음과 같은 서명을 가진 생성자가 있습니다.

JDialog(Frame, String, boolean, GraphicsConfiguration)
JDialog(Dialog, String, boolean, GraphicsConfiguration)

GraphicsConfiguration을 설정하고 싶기 때문에이 생성자를 사용해야하지만이 대화 상자의 부모가 없으므로 첫 번째 인수는 null이어야합니다. 사용

JDialog(null, String, boolean, Graphicsconfiguration) 

모호 하므로이 경우 지원되는 유형 중 하나로 null을 캐스팅하여 호출 범위를 좁힐 수 있습니다.

JDialog((Frame) null, String, boolean, GraphicsConfiguration)

0

이 언어 기능은이 상황에서 편리합니다.

public String getName() {
  return (String) memberHashMap.get("Name");
}

memberHashMap.get ( "Name")이 null을 반환하는 경우 위의 메서드가 예외를 발생시키지 않고 null을 반환하도록하려는 경우가 있습니다. 클래스가 무엇이든 null은 null입니다.

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