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;
}
}
}
'Java' 카테고리의 다른 글
왜 interface인가, interface가 갖는 의의와 목적 (0) | 2018.07.13 |
---|---|
추상 메소드(abstract method)의 목적, 용도, 쓰임새(추상 메소드를 만드는 이유) (0) | 2016.05.16 |
BufferedReader에 대한 개념 세우기 (0) | 2015.11.04 |
String을 byte[] 배열로 변환하는 법 - getBytes() 메소드에 대해 (0) | 2015.11.04 |
Map과 List에 대한 간단한 이해 (0) | 2015.10.30 |