IT

NullPointerException이 발생하지 않는 이유는 무엇입니까?

lottoking 2020. 9. 7. 08:24
반응형

NullPointerException이 발생하지 않는 이유는 무엇입니까?


다음 코드에 대한 명확한 설명 :

StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
referToSample.append("B");
System.out.println(sample);

B증명 samplereferToSampleobject-가 동일한 메모리 참조를 참조하도록 인쇄됩니다 .

StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
sample.append("A");
referToSample.append("B");
System.out.println(referToSample);

이것은 AB또한 동일한 것을 증명하는 인쇄됩니다 .

StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
referToSample = null;
referToSample.append("A");
System.out.println(sample);

분명히 이것은 null 참조 NullPointerExceptionappend합니다.

StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
referToSample = null;
sample.append("A");
System.out.println(sample);

그래서 여기 내 질문 NullPointerException이 있습니다. 처음 두 예제에서보고 이해하는 것은 두 개체가 동일한 개체를 참조하는 경우 값을 변경하면 두 개체가 모두를 가리키고 있기 때문에 다른 개체에도 반영되기 때문에 마지막 코드 샘플이 던지지 않는 이유는 무엇입니까? 동일한 메모리 참조. 거기에 적용되지 않는 이유는 무엇입니까? nullreferToSample에 할당 하면 샘플도 null이어야하며 NullPointerException을 throw해야하지만 던지지 않는 이유는 무엇입니까?


null할당은 해당 개체를 전체적으로 삭제하여 변경하지 않습니다 . 상황 종류의 행동은 추적하기 어려운 버그와 반 가능성 인 행동으로 이어질 것입니다. 그들은 특정 참조를 깨뜨 립니다.

하게 간단 sample하기 위해 주소 12345 가리키고 있다고 가정 해 보겠습니다. 이것은 주소가 아닐 수 있습니다. 여기에서 간단하게 만드는 데만 사용됩니다. 주소는 일반적으로에 이상한 16 진수로 표시 Object#hashCode()구현에 따라 표시 됩니다. 1

StringBuilder sample = new StringBuilder(); //sample refers to 
//StringBuilder at 12345 

StringBuilder referToSample = sample; //referToSample refers to 
//the same StringBuilder at 12345 
//SEE DIAGRAM 1

referToSample = null; //referToSample NOW refers to 00000, 
//so accessing it will throw a NPE. 
//The other reference is not affected.
//SEE DIAGRAM 2

sample.append("A"); //sample STILL refers to the same StringBuilder at 12345 
System.out.println(sample);

내가 See diagram말하는 개체의 다이어그램은 다음과 같다.

다이어그램 1 :

[StringBuilder sample]    -----------------> [java.lang.StringBuilder@00012345]
[StringBuilder referToSample] ------------------------/

다이어그램 2 :

[StringBuilder sample]    -----------------> [java.lang.StringBuilder@00012345]

[StringBuilder referToSample] ---->> [null pointer]

다이어그램 2는 무효화 referToSamplesample에서 StringBuilder에 대한 참조를 중단하지 않고 보여 보여줍니다 00012345.

1 GC 고려 사항으로 인해이를 믿을 수 없습니다.


처음에는 다음 과 같이 referToSample언급 sample한대로 였습니다 .

1. 시나리오 1 :

referToSample은 샘플을 참조합니다.

2. 시나리오 1 (연속) :

referToSample.append ( "B")

  • 여기에서 referToSample를 참조 sample했으므로 작성하는 동안 "B"가 추가되었습니다.

    referToSample.append("B")

Scenario2 에서도 동일한 일이 발생했습니다 .

그러나 3. Scenario3에서 : hexafraction이 말했듯이,

참조 할당 nullreferToSamplesample변경하지 않았습니다. 대신 참조끊고 이제 아무데도 가리 키지 않습니다 . 아래 그림과 같이:sample

referToSample = null 인 경우

이제 아무데도referToSample 점이 없으므로 A를 추가 할 수있는 값이나 참조가 없습니다. 따라서 .referToSample.append("A");NullPointerException

그러나 sample초기화 한 것과 여전히 동일합니다.

StringBuilder sample = new StringBuilder(); 초기화되었으므로 이제 A를 추가 할 수 있습니다. NullPointerException


간단히 말해서, 객체가 아닌 참조 변수에 null을 할당합니다.

한 예 에서 두 개의 참조 변수가 참조하는 객체 상태 를 변경합니다 . 이 경우 두 참조 변수 모두 변경 사항을 반영합니다.

또 다른 예에서는 하나의 변수에 할당 된 참조를 변경하지만 이것은 객체 자체에는 영향을주지 않으므로 원래 객체를 참조하는 두 번째 변수는 객체 상태의 변화를 인식하지 못합니다.


특정 "규칙"에 관해서 :

두 객체가 동일한 객체를 참조하는 경우 값을 변경하면 둘 다 동일한 메모리 참조를 가리 키기 때문에 다른 값도 반영됩니다.

다시 말하지만, 변수가 참조 하는 한 개체 상태 를 변경하는 것을 참조합니다.

그렇다면 그 규칙이 여기에 적용되지 않는 이유는 무엇입니까? referToSample에 null을 할당하면 sample도 null이어야하며 nullPointerException을 throw해야하지만 throw되지 않는 이유는 무엇입니까?

다시 말하지만, 다른 변수 참조전혀 영향주지 않는 한 변수 참조 를 변경합니다 .

이것은 완전히 다른 두 가지 작업이며 두 가지 완전히 다른 결과를 초래합니다.


이 간단한 다이어그램을 참조하십시오.

도표

당신이 호출 할 때 방법referToSample, 다음 [your object]이 영향을 미치는, 그래서 업데이트됩니다 sample너무. 당신이 말할 때 referToSample = null, 당신은 단순히 무엇을 변경하고 referToSample 의미 합니다.


여기서 'sample'과 'referToSample'은 동일한 객체를 참조하는 것으로 동일한 메모리 위치에 액세스하는 다른 포인터의 개념입니다. 따라서 하나의 참조 변수를 null에 할당해도 객체가 파괴되지 않습니다.

   referToSample = null;

'referToSample'은 null 만 가리키고 객체는 동일하게 유지되며 다른 참조 변수가 제대로 작동 함을 의미합니다. 따라서 null을 가리 키지 않고 유효한 객체를 갖는 'sample'의 경우

   sample.append("A");

잘 작동합니다. 그러나 'referToSample'에 null을 추가하려고하면 NullPointException이 표시됩니다. 그건,

   referToSample .append("A");-------> NullPointerException

이것이 세 번째 코드 조각에서 NullPointerException이 발생한 이유입니다.


키워드가 사용될 때마다 힙에 객체를 생성합니다.

1) StringBuilder 샘플 = new StringBuilder ();

2) StringBuilder referToSample = 샘플;

2) referSample의 참조가 동일한 객체 샘플에 생성됩니다.

따라서 referToSample = null; 샘플에 영향을 미치지 않는 referSample Reference 만 Nulling이므로 Java의 Garbage Collection 덕분에 NULL 포인터 예외가 발생하지 않습니다.


간단합니다. Java는 참조로 전달하지 않고 객체 참조 만 전달합니다.

참고 URL : https://stackoverflow.com/questions/18636561/why-is-this-not-throwing-a-nullpointerexception

반응형