Java의 Reference 타입 자료형에 대해


자바의 자료형은 크게 기본형과 레퍼런스 타입으로 분류할 수 있다. 

레퍼런스 타입은 new 연산자를 통해서 힙(heap) 영역에 생성되는 자료형들을 의미한다. 

레퍼런스 타입으로는 클래스, 배열, 인터페이스 들이 있다.


따라서 arr1, arr2라는 2개의 배열이 있을 때 

arr1 = arr2;

를 하면 arr2에 있는 데이터를 arr1에 대입하는 것이 아니라(call-by-value가 아니라)

arr2가 가리키는 메모리 주소 값을 대입한다(call-by-reference이다). 


따라서 arr1에서 값을 변경하면arr2에서도 값이 변경된다. 

반대로 arr2에서 값을 변경하면 arr1의 값도 동시에 바뀐다.


그러나 

int arr1, int arr2;


가 있다면 이때 

arr1 = arr2;


라고 하면 이건 값(데이터)을 대입한다. 즉 call-by-value이다. 

따라서 arr1의 값을 변경해도 arr2에는 아무런 영향이 없고

arr2의 값을 변경해도 arr1에는 아무런 영향이 없다.


그런데 배열은 근본적으로 call-by-reference이다. 

따라서 아래 코드에서 

mRGBData를 chageData(byte[] rgb)로 넘기면 

mRGBData와 rgb는 동일한 기억 장소를 가리키게 된다. 

따라서 changeData()에서 mRGBData에 값을 대입하는 것이 전혀

없을지라도 mRGBData를 출력해 보면 changeData()에서 수정한 값이 잘 출력된다.


public class MainActivity extends Activity {

private TextView txt;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

txt = (TextView)findViewById(R.id.txt);

byte[] mRGBData = null;

mRGBData = new byte[5];

changeData(mRGBData);

String str = "";

for (int i=0; i<mRGBData.length; i++) {

str += mRGBData[i] + ", ";

}

txt.setText(str);

} //onCreate

private void changeData(byte[] rgb) 

{

for(int j=0; j<rgb.length; j++) {

//여기서 mRGBData에 값을 대입하지 않고 rgb에만 값을 넣었는데도

//onCreate()에서 TextView에 mRGBData를 출력해 보면 0, 2, 4, 6, 8이 출력된다.

rgb[j] = (byte)(j*2);

}

}

}



아래와 같이 class도 reference type이다. class 참조변수(객체)에 대입을 하면 value가 대입되는 것이 아니라

reference가(해당 클래스의 기억장소 주소 값이) 대입 되게된다.

그래서 class의 두 참조 변수는 동일한 기억 장소를 가리키게 된다.


public class MainActivity extends Activity {

private TextView txt;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

txt = (TextView)findViewById(R.id.txt);

MyClass myClass = new MyClass();


//아래 로그를 출력해 보면 다음과 같이 My2클래스에서 myc와 mc를 출력했을 때와 같이

//동일한 기억장소를 가리키게 된다.

// myClass : com.example.test.MainActivity$MyClass@411e71c0

Log.e("$$$$$$$", "myClass : "+myClass.toString());

My2 my2 = new My2(myClass);

String str = myClass.name + "\n" + myClass.age;

txt.setText(str); 

} //onCreate

class MyClass

{

private String name;

private int age;

}

class My2

{

private long kkk;

MyClass myc;

public My2(MyClass mc)

{

myc = mc;

//아래 로그를 출력해 보면

//myc : com.example.test.MainActivity$MyClass@411e71c0

Log.e("$$$$$$$", "myc : "+myc.toString());


//아래 로그를 출력해 보면

//mc : com.example.test.MainActivity$MyClass@411e71c0

Log.e("$$$$$$$", "mc : "+mc.toString());

mc.name = "홍길동";

mc.age = 29;

}

}

}



+ Recent posts