2013-07-27 3 views
-4

go 메서드 내에서 c2이 null이기 때문에 다음 프로그램의 결과에 NullPointerException이 출력 될 것으로 예상됩니다. 하지만 제대로 작동하고 200 장 인쇄됩니다. 왜?왜 NullPointerException이 발생하지 않습니까?

class CardBoard { 
    Short story = 200; 
    CardBoard go(CardBoard cb) { 
     cb = null; 
     return cb; 
    } 
    public static void main(String[] args) { 
     CardBoard c1 = new CardBoard(); 
     CardBoard c2 = new CardBoard(); 
     CardBoard c3 = c1.go(c2); 
     System.out.print(c2.story); // dout here 
    } 
} 

답변

1

당신은 null로 go 함수의 매개 변수를 가리키고 아닌 c2 변수입니다. go 메서드는 실행시 CardBoard 매개 변수의 내용을 변경할 수 있지만 (예 : story 매개 변수) 개체 자체는 '제외'되지 않습니다.

+0

; 같은 NPE를 슬로우' 'c3'는'null'을 할당 받게됩니다. – akf

+0

지금 막 편집 된 내용 ...? – user1612062

+0

@akf : 아마도 그는 NPE를 받고있을 것입니다. – drvdijk

0
  • 참조 to c2가 go 메소드에 전달됩니다.
  • 는 기준이 메소드 코드는 가변 파라미터에 널을 ​​할당 파라미터 CB
  • 에 할당

이 모든 이동 방법

1

외부 C2 변수의 내용에 영향을주지 Java는 메소드 호출에 pass by value semantics을 사용합니다. 즉, c2에 대한 참조 값은 참조 자체가 아닌 go 메서드로 전달됩니다. 이것을 이렇게 생각하십시오. main에서 생성 된 개체를 가리키는 값을 포함하는 메모리 슬롯이 4 개 있으며이 메모리 슬롯은 각각 c1, c2c3으로, cb이라는 go 메서드로 전달 된 값을 보유합니다. 함수가 호출되면 c2의 값이 슬롯 cb에 복사됩니다. 그런 다음 go 메서드는 null 값을 슬롯 cb에 넣습니다. 그러나이 값은 슬롯 c2의 값을 변경하지 않으며 메서드 호출 이전과 동일하게 유지됩니다.

1

Is Java pass-by-value?.

r2c2에 대한 참조라고하면, 123은 그 참조의 값입니다. so r2 "보유" 위치 이외에 123입니다.

이제 c1.go(c2)을 호출하면 123을 보유하는 새로운 참조 rN이 만들어지고 메서드에 전달됩니다. 그리고 c2 = null을 할 때 null이되고 c2이 아닌 것은 rN입니다.

0

은 예상 된 결과가 nullingCBgo 방법 내부

`System.out.print(cb.story);` 

를 사용하려고 얻으려면.

또는 이제 경우에 당신이 c3에 할당 null을 반환하는

System.out.print(c3.story); // dout here 

. 그래서 당신은 c2 변수를 수정하지 않습니다.

나는이 의문에 대해 발견 한 가장 좋은 explaination는 here

모든 답변과 의견은 읽을 가치가있다.

1

자바 매개 변수는 참조가 아닌 값으로 전달되므로 c2 변수를 수정하지 않으므로 c2이 가리키는 objet를 "전달"하는 것입니다. 당신이 자신을 c2 수정 될

다음
class CardBoard { 

    Short story = 200; 

    CardBoard go(byRef CardBoard cb) { // NOT REALLY ALLOWED, Compilation error 
     cb = null; 
     return cb; 
    } 

    public static void main(String[] args) { 
     CardBoard c1 = new CardBoard(); 
     CardBoard c2 = new CardBoard(); 
     CardBoard c3 = c1.go(byRef c2); // NOT REALLY ALLOWED, Compilation error 
     System.out.print(c2.story); // dout here 
    } 
} 

,하지만 당신은 수정할 수있는 유일한 방법은 객체의 내부 상태가 될 것입니다 :

당신은 C#을 같은 언어를 사용하고 어쩌면 경우 자바에서이 작업을 수행 할 수 당신은 (myObj.setSomething(x)과 같은 것을 호출하는) 패스합니다.

0

난 당신이 참조와 객체가 주요 기능을

CardBoard c1 = new CardBoard(); 

c1 |100| Address ---points to---> Memory address at location 100 

     CardBoard c2 = new CardBoard(); 
c2 |400| Address ---points to---> Memory address at location 400 

     CardBoard c3 = c1.go(c2); 
c3 |600| Address ---points to---> Memory address at location 600 

     System.out.print(c2.story); // dout here 

이동 기능

CardBoard go(CardBoard cb) { 

cb |400| Address ---points to---> Memory address at location 400 

New cb reference is created which also points to memory location where c2 is pointing(Note, cb and c2 are two different reference but pointing to same memory location) 

    cb = null; 
Above line changed cb reference to null, still c2 is pointing to same memory location. 
     return cb; 
    } 

이동 기능이 돌아 왔을 때 그래서 C2에 변화가없는 작동 방법에 의해 오해 생각합니다.

cb 참조에서 스토리 변수를 변경해보십시오. 변수가 c2 변수에도 영향을주는 것을 볼 수 있습니다.

CB를 생성 한 다음 C1, C2 및 C3 다른 방법 스택 생성

그도 System.out.print (c3.story)`생각 될 수
관련 문제