들어가면서
java는 call by value일까요? call by reference일 까요?
책이나 여타 문서를 보면 대부분 call by value라고 쓰여 있고 개중에는 반쪽짜리 call by reference라고 쓰여 있습니다.
어떤 책/문서에는 call by reference라고 쓰여 있기도 하고...
퀴즈
public class ReferenceVSvalue {
private String message = null;
private int data = 0;
public ReferenceVSvalue(String message, int init) {
this.message = message;
this.data = init;
}
public static void plusType1(ReferenceVSvalue r) {
r.data++;
}
public static void plusType2(ReferenceVSvalue r) {
r = new ReferenceVSvalue("두번째 객체", 50);
r.data++;
}
public static void print(ReferenceVSvalue r) {
System.out.println(r.message + "의 value : " + r.data);
}
public static void main(String[] args) {
ReferenceVSvalue instance = new ReferenceVSvalue("첫번째 객체", 20);
plusType1(instance);
print(instance);
plusType2(instance);
print(instance);
}
}
결과
결과가 어떻게 나올까요?
첫번째 객체의 value : 21
첫번째 객체의 value : 21
첫번째 객체의 value : 21
두번째 객체의 value : 51
위 소스에 call by value라고 가정해 보면 (가정이 아니 결론이지만..) main method의 마지막 print()까지 흘러 가고 내부적으로 GC가 발생하면 어떤 객체가 소멸되어야 할까요? 'new ReferenceVSvalue("두번째 객체", 50);'가 소멸될 것입니다. 반대로 call by reference라고 한다면 'new ReferenceVSvalue("첫번째 객체", 20);'가 소멸될 것입니다.
finalize()를 추가한 예제
import java.util.Date;
public class ReferenceVSvalue {
private Date createDate = null;
private String message = null;
private int data = 0;
public ReferenceVSvalue(String message, int init) {
createDate = new Date();
this.message = message;
this.data = init;
}
protected void finalize() throws Throwable {
System.err.println(createDate + "에 생성된 객체가 GC가 되려고 합니다. (" + message + ")");
super.finalize();
}
public static void plusType1(ReferenceVSvalue r) {
r.data++;
}
public static void plusType2(ReferenceVSvalue r) {
r = new ReferenceVSvalue("두번째 객체", 50);
r.data++;
}
public static void print(ReferenceVSvalue r) {
System.out.println(r.message + "의 value : " + r.data);
}
public static void main(String[] args) {
ReferenceVSvalue instance = new ReferenceVSvalue("첫번째 객체", 20);
plusType1(instance);
print(instance);
plusType2(instance);
print(instance);
// 아무 의미 없음.. 그냥 sleep
try {
System.gc();
Thread.sleep(1000 * 1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
결과
첫번째 객체의 value : 21
Tue Apr 24 09:36:26 KST 2007에 생성된 객체가 GC가 되려고 합니다. (두번째 객체)
위에서 설명드린 것 처럼 GC되는 객체는 '두번째 객체'로 나오는 군요.
따라서 plusType2 method에서 'new ReferenceVSvalue("두번째 객체", 50);' 은 자신의 method에서만 유효한 값이라는 의미가 됩니다.
@