자바에서의 객체생성
글쓴이: gohy / 작성시간: 월, 2017/09/04 - 8:21오후
아래의 소스 결과가 제가 예상할때는
----
A
B
----
이렇게 나올거라 예상하는데
----
A
A
----
로 나오는 것을 보고 제가 자바에 대해서 제대로 이해하지 못하고 있구나 생각이 들었습니다.
new에 대한 스코프가 따로있는건지.. 만약에 setMemberB 를 통해서 var1이 새로운 객체를 참고하고 거기서 생성된 객체가 setMemberB 가 끝나면서 소멸됬다면은 var1은 기존의 객체가 아니라 null로 나와야 될 것 같은데...
조언 부탁드립니다..
class A{ public String member; public A(String param) { member = param; } } public class ApplianceTest { public static void main(String[] args) { A var1 = new A("A"); System.out.println(var1.member); setMemberB(var1); System.out.println(var1.member); } public static void setMemberB(A param) { param = new A("B"); } }
Forums:
자바는 모릅니다만,
자바는 모릅니다만,
함수의 인자가 참조가 아닌 값으로 전달되는 것으로 보이네요.
#1. new A("A");
#1. new A("A");
구문(expression) `new A("A")` 는 새로운 객체를 만듭니다. 만들어진 객체는 JVM이 판단하기에 더 이상 필요 없어질 때까지 살아있습니다. 더 이상 필요 없어지면 garbage collection의 대상이 되고 적절한 시점에 소멸됩니다. 정확히 언제 소멸될 지는 아무런 보장이 없습니다.
#2. A var1 = ...
`var1`은 #1의 구문을 통해서 만들어진 객체에 대한 레퍼런스(참조, 별명, alias)입니다. 자바에서 객체에 대한 변수는 항상 레퍼런스입니다.
#3.
public static void setMemberB(A param) ...
setMemberB(var1);
자바에서 함수 인자는 항상 "값"으로 전달됩니다 (call by value). 즉 `param`은 레퍼런스 `var1` 의 복사본입니다. 다시 말해 `param`도 #1에서 만들어진 그 객체에 대한 레퍼런스인거지요. 고로`param = new A("B")` 와 같은 대입은 `var1`과 아무 관련도 없습니다. 단순히 `param`이 이제는 `new A("B")` 구문을 통해 만들어진 새로운 객체를 참조하도록 만들 뿐입니다.
#4.
처음에 기대하신 것처럼 `param = new A("B")` 가 `var1 = new A("B")` 과 같은 효과를 갖도록 하는 인자 전달 방식을 "call by name" 이라고 합니다. 현재는 자바뿐만 아니라 어떤 언어에서도 사실상 사용되지 않는 방식입니다. 그런 방식을 사용하면 매우 이해하기 힘든 (다시 말해 버그가 생기기 쉬운) 코드가 나오기 쉽습니다.
#5.
> 소멸됬다면은 var1은 기존의 객체가 아니라 null로 나와야 될 것 같은데
어떤 변수에 명시적으로 null literal을 대입하거나 값이 null인 변수를 대입하지 않는 이상 null이 아니었던 변수가 null이 되는 경우는 없습니다. 아직 어떤 변수를 사용하고 있는데 그 변수가 참조하고 있던 객체가 소멸되는 것은 일반적인 garbage collection의 목적과 정면으로 어긋납니다.
댓글 달기