다음 코드에 대한 명확한 설명 :
StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
referToSample.append("B");
System.out.println(sample);
B
증명 sample
과 referToSample
객체가 동일한 메모리 참조를 참조하도록 인쇄됩니다 .
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 참조 NullPointerException
를 호출하려고하기 때문에 분명히 이것은 던질 것 append
입니다.
StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
referToSample = null;
sample.append("A");
System.out.println(sample);
그래서 여기에 내 질문 NullPointerException
이 있습니다. 처음 두 예제에서보고 이해하는 것은 두 개체가 동일한 개체를 참조하는 경우 값을 변경하면 두 개체가 모두를 가리키고 있기 때문에 다른 개체에도 반영되기 때문에 마지막 코드 샘플이 던지지 않는 이유는 무엇입니까? 동일한 메모리 참조. 그렇다면 그 규칙이 여기에 적용되지 않는 이유는 무엇입니까? null
referToSample에 할당 하면 샘플도 null이어야하고 NullPointerException을 throw해야하지만 throw하지 않는 이유는 무엇입니까?
답변
null
할당은 해당 개체를 전체적으로 삭제하여 값 을 변경하지 않습니다 . 그런 종류의 행동은 추적하기 어려운 버그와 반 직관적 인 행동으로 이어질 것입니다. 그들은 단지 그 특정 참조를 깨뜨 립니다.
간단하게 sample
하기 위해 주소 12345 를 가리키고 있다고 가정 해 보겠습니다. 이것은 주소가 아닐 수 있으며 여기서 일을 간단하게 만드는 데만 사용됩니다. 주소는 일반적으로에 제공된 이상한 16 진수로 표시 1Object#hashCode()
되지만 구현에 따라 다릅니다.
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는 무효화 referToSample
가 sample
에서 StringBuilder에 대한 참조를 중단하지 않음을 보여줍니다 00012345
.
1 GC 고려 사항으로 인해이를 믿을 수 없습니다.
답변
처음에는 아래에 표시된대로 referToSample
언급 sample
한대로 였습니다 .
1. 시나리오 1 :
2. 시나리오 1 (계속) :
-
여기에서
referToSample
를 참조sample
했으므로 작성하는 동안 “B”가 추가되었습니다.referToSample.append("B")
Scenario2 에서도 같은 일이 발생했습니다 .
그러나 3. Scenario3에서 : hexafraction이 말했듯이,
참조 할 때 할당 null
할 referToSample
때 값 을 sample
변경하지 않았습니다. 대신 참조 를 끊고 이제 아무데도 가리 키지 않습니다 . 아래 그림과 같이:sample
이제 아무데도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는 참조로 전달하지 않고 객체 참조 만 전달합니다.