Java에서 메서드가 지역변수인 객체를 반환하는 것이 가능한가요?

canuyes의 이미지

안녕하세요.

Java 공부중에 친구와 논쟁(?)을 한 부분이 있어 질문 올립니다.

저는 평소에 C++를 사용하다가 Java로 슬슬 옮겨가는 중입니다.
C++에서는 분명 아래와 같은 코드가 에러인 것으로 알고 있는데,
(반환시에 지역변수 c1의 깊은 복사가 이뤄지지 않을 뿐더러, methodC2를 벗어날 때, c1이 자동으로 소멸되기 때문에)
제 친구는 Java는 어떠한 객체라도 참조하고 있는 변수가 하나라도 있으면 소멸이 이뤄지지 않아 에러가 아니라고 합니다.
어떤 것이 맞는 것인가요??

class C1{
      String name;
 
}
 
class C2{
      C1 methodC2()
      {
         C1 c1;
         return c1;
      }
}
HDNua의 이미지

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이라는 방법을 씁니다만 그건 나중에 기회가 될 때 찾아보시는 게.

일단 이 정도로 답변 드립니다.

저는 이렇게 생각했습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.