2015년 11월 8일 일요일

Java의 Reference 타입(레퍼펀스 타입) 자료형에 대해





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;
}
}
}

댓글 없음:

댓글 쓰기