Java에서 메서드가 지역변수인 객체를 반환하는 것이 가능한가요?
글쓴이: canuyes / 작성시간: 토, 2014/10/04 - 1:24오후
안녕하세요.
Java 공부중에 친구와 논쟁(?)을 한 부분이 있어 질문 올립니다.
저는 평소에 C++를 사용하다가 Java로 슬슬 옮겨가는 중입니다.
C++에서는 분명 아래와 같은 코드가 에러인 것으로 알고 있는데,
(반환시에 지역변수 c1의 깊은 복사가 이뤄지지 않을 뿐더러, methodC2를 벗어날 때, c1이 자동으로 소멸되기 때문에)
제 친구는 Java는 어떠한 객체라도 참조하고 있는 변수가 하나라도 있으면 소멸이 이뤄지지 않아 에러가 아니라고 합니다.
어떤 것이 맞는 것인가요??
class C1{
String name;
}
class C2{
C1 methodC2()
{
C1 c1;
return c1;
}
}Forums:


답변
1. 일단 위 코드는 C++에서도 오류가 아닙니다.
C++이 다른 객체 지향 언어와 다른 중요한 특성 중의 하나는, C++의 객체는 지역 변수와 같이 스택에 생성할 수 있다는 점입니다.
class Object1 { }; class Object2 { Object1 method() { // Object1 형식의 객체를 반환하는 함수 Object1 object; // Object1 형식의 객체가 스택에 생성 return object; // object를 반환: object의 사본이 반환된다. 여기서 생성한 object와 반환된 객체는 정보만 같은 다른 객체라는 뜻 } };위의 코드는 전혀 틀린 게 아닌 게, 위와 같이 되어있으면 반환하는 것은 지역 변수 자체가 아닌 지역 변수의 사본이기 때문입니다.
만약 다음과 같이 참조자를 써서 반환한다 하면.. 지역 변수의 범위가 종료되기 때문에 문제가 발생하는 것이지요.
Object1& method() { // Object1 형식의 객체에 대한 참조를 반환하는 함수 Object1 object; // Object1 형식의 객체가 스택에 생성 return object; // object 자체가 반환된다. 여기서 생성한 object와 반환된 객체는 서로 같은 객체 }만약 변수에 대한 참조를 반환하고 싶다면 이미 참조가 있는 변수를 반환하던지, 포인터를 이용하던지 해야 합니다.
Object1* method() { Object1 objectPointer = new Object1(); // 힙에 Object1 객체 생성 return objectPointer; // 포인터가 반환되어도 힙에서 메모리가 사라지지 않습니다. 당연하지요? }2. Java에서 위와 같은 코드가 작성되어도 틀리지 않습니다. Java의 객체 변수 선언은 객체에 대한 참조를 가리키며 그 자체가 객체는 아닙니다.
말을 좀 이상하게 한 것 같은데, Java에서 클래스를 선언하고 클래스 변수를 만든다면 만든 모든 변수는 포인터라고 생각해야 합니다.
class MyObject1 {} class MyObject2 { MyObject1 method() { MyObject1 object = new MyObject1(); // Java의 객체는 '무조건' 힙에 할당됩니다. C++에서는 객체를 스택에 할당할 수 있었고 return object; // 따라서 함수가 끝나면 지역이 종료되어 객체도 사라졌지만 Java에서는 힙에 할당되기 때문에.. 그렇지 않습니다. } } class Program { public static void main() { MyObject2 object2 = new MyObject2(); MyObject1 object1 = object2.method(); // method 내부에서 생성된 객체와 object1은 동일한 객체를 '가리킵니다'. } }다시 한 번 말씀드리자면 Java에서의 모든 클래스 변수는 객체에 대한 포인터라고 생각해야 합니다.
결론.
1) 코드는 안 틀렸다
2) Java에서는 객체가 참조되고 있다면 해제되지 않는다
참조되고 있지 않은 객체에 대한 삭제는 Java에서는 Garbage Collection이라는 방법을 씁니다만 그건 나중에 기회가 될 때 찾아보시는 게.
일단 이 정도로 답변 드립니다.
저는 이렇게 생각했습니다.
댓글 달기