2015-02-05 3 views
3

나는 뭔가를 시도하고 있었고이 흥미로운 시나리오를 발견했습니다. 이 두 단편의 주요 차이점을 이해하고 싶었습니다.Java의 참조 동작 이해

초기에는 두 세트를 초기화하고 하나를 초기화하고 other에 대한 참조를 할당했습니다. I가 설정 취소하면 내가 설정 B 크기가이의 출력이 같은 있었다뿐만 아니라

Set<String> A = new HashSet<String>(); 
A.add("hello"); 
A.add("HEY"); 
A.add("hey"); 
Set<String > B = A; 

System.out.println("initial sizes :" + A.size() + " " + B.size()); 
A.clear(); 
System.out.println("final sizes :" + A.size() + " " + B.size());  

0으로 변경 것으로 나타났습니다 : 이제

initial sizes :3 3 
final sizes :0 0  

, 나는에 대해 동일한 동작을 묘사하는 시도 객체를 다음과 같이

Object a1 = new Object(); 
Object b1 = a1; 
System.out.println("initial sizes :" + b1.toString() + " " + a1.toString()); 
a1 = null; 
System.out.println("initial sizes :" + b1.toString() + " " + a1); 

이의 출력은 무언가 같은 :

initial sizes :[email protected] [email protected] 
initial sizes :[email protected] null 
여기에 정확한 차이가 무엇

, 나는 내가 여기 b1.toString()

+3

@ ha9u63ar 자바에서 모든 것이 값으로 전달됩니다. 참조에 맞을 수도 있지만 객체에 대한 참조도 값으로 전달됩니다. – SomeJavaGuy

+0

@KevinEsche 게시하기 전에 내 의견을 수정하고있었습니다. 사과. – ha9u63ar

+0

코드 스 니펫에서'Object'를 사용하여 출력을 얻는 방법을 잘 모르겠습니다 - [this] (http://ideone.com/pZWzNl) – ha9u63ar

답변

3

의 차이를 인쇄하려고 할 때 NullPointerException이를 얻기 위해 기다리고 있었다, a1b1 그 객체에 대한 객체 자체 만 참조가 아니라는 것이다. 따라서 a1이 참조하는 개체를 수정하면 b1 (동일한 개체)이 참조하는 개체도 변경됩니다. 그러나 a1이 다른 인스턴스 (이 경우 null)를 가리 키도록 지시하면 더 이상 동일한 객체를 참조하지 않으므로 변경하면 b1에 영향을 미치지 않습니다.

조금 더 자세히 들어가려면 : Java는 값이입니다. 그러나 원시 값이 아닌 객체를 전달하려고하면 참조의 값 (실제로는 이라는 핸들이라고도 함)을 전달합니다. 그래서 때로는 Java가 또는 의 패스로 전달되는지 여부를 확인하려고 할 때 때때로 약간 혼란 스러울 수 있습니다.으로 전달하십시오.

+0

obj1 = obj2 (둘 다 같은 메모리 위치에 있습니다) 어디 obj1.clone (obj2) 그들은 서로 다른 메모리 위치에 있습니다) –

+0

@DaveP 당신은 "*와 같은 의미가 있습니다. b1 **에 의해 참조되는 객체 (동일한 객체) ** ... * "? – blalasaadri

4

를 들어 프리미티브 같은 int, double, float 등, 만들어지는 의 사본 및 그 값에 의해 전달되는 등 : -

여기
int x = 10; 

public void foo(int k){ 

} 

foo(x) 

k가의 사본을 얻을 것이다 x에 저장된 값이 k 일 때 값이이고 10이됩니다. 그러나 xy은 두 가지 차이가 ​​있습니다 메모리 위치를 대여하십시오. x의 값을 변경하더라도 k의 값은 변경되지 않습니다.

개체 참조 참조 사본이 만들어지고 값으로 전달됩니다 (참조는 일부 메모리의 주소 이상입니다). 따라서 본질적으로 두 참조 모두 동일한 객체 (즉, 동일한 메모리 위치)를 가리킬 것입니다.

Myobject m = new Myobject(); 

public void bar (Myobject j){ 

} 

bar(m) 

기준 m 값의 사본을 만들어 j에 할당한다. mj은 이제 동일한 개체를 가리 킵니다.

2

이미지를 확인하십시오. A2/A3은 bojects에 대한 참조입니다. 첫 번째 경우는 Set (이미지의 a1)에 대한 참조입니다. 하나의 참조가 객체를 수정하면 두 번째 참조는 동일한 변경을 봅니다.

한편 reference = null을 설정하면 그림에서 "한 개의 화살표 지우기"가됩니다. 참조는 객체를 가리 키지 않지만 다른 참조는 여전히 객체를 가리 킵니다.

enter image description here

0

당신은 자바가 다른 객체도 참조 값으로 전달되는 값에 의해 completly 패스 인 것으로 나타났습니다.

개체를 널 (null)로하면 실제로 개체를 널링하지 않고 어떤 개체가 동일한 개체에서 실행될 수 있습니다. 개체에 대한 참조의 값만 null입니다.

원래 목록의 메소드를 계속 실행할 수있는 동안이 예제를 선택하면 목록 1의 참조 값이 널 (null)이됩니다. 목록 1의 방법

ArrayList<Integer> list1 = new ArrayList<Integer>(0); 
list1.add(1); 
list1.add(2); 
ArrayList<Integer> list2 = list1; 
list1.clear(); 
list1 = null; 

System.out.println(list2.size()); 
System.out.println(list1.size()); // will cause an nullpointerexception 

호출은리스트 2에 영향을하지만, 객체 목록 1 실 거예요 목록 1

0

내 대답은 @ I.K에 추가 요소에게 영향을 제로 화시키는 않습니다. 대답. 프리미티브 (값의 복사본)와 비 프리미티브 (참조 값의 복사본) - 이것이 핵심적인 이해입니다.

(IDEONE에서 호스팅) 내가 코멘트를 넣어 가지고이 코드에서

봐 :

수입는 java.io *;

/* Name of the class has to be "Main" only if the class is public. */ 
class Ideone 
{ 
    public static void main (String[] args) throws java.lang.Exception 
    { 
     String a1 = "blablabla"; 
     String b1 = a1; 

     System.out.println(b1); 
     System.out.println(a1);  

     System.out.println(b1.hashCode()); 
     System.out.println(a1.hashCode()); 

     a1 = "wow"; 

     System.out.println(b1.hashCode()); 
     System.out.println(a1.hashCode()); 

     System.out.println(b1); 
     System.out.println(a1);  

     Set<String> a = new HashSet<String>(); 

     Set<String> b = a; 

     a.add("hey"); 
     a.add("HellO"); 

     System.out.println(b.size()); 
     System.out.println(b.hashCode()); // e.g. 69712814 
     System.out.println(a.hashCode()); // same - 69712814 (It's important to know) 

     a.clear(); 

     System.out.println(a.size()); // same hashcode i.e. gets affected by the change. 
     System.out.println(b.size()); 

동일한 코드를 사용하면 효과적으로 해시 된 것을 볼 수 있습니다.

String 클래스는 "Intern"값에 문자열 풀을 사용한다는 것을 알고 있기 때문에 Java에서는 약간 특별합니다. 위의 코드를 실행하면 a1 = "wow";을 수행하자마자 풀에 새로운 값 "와우"가 생성되므로 hashCode()가 변경된다는 것을 알 수 있습니다.