정말 아리송하네요 자바.
public class Test {
public static void tricky(Point arg1, Point arg2){
arg1.x = 100;
arg1.y = 100;
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}
public static void main (String [] args) {
Point pnt1 = new Point (0,0);
Point pnt2 = new Point (0,0);
System.out.println("X: " + pnt1.x + " Y: " + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " + pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y: " + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " + pnt2.y);
}
}
class Point {
public int x;
public int y;
public Point(int x, int y) {
this.x=x;
this.y=y;
}
}
예상 결과값은
0 0
0 0
0 0
100 100
근데.. 사실은 다르네요. ㅠ.ㅠ. 왜그러죠?
로컬변수 개념을 잘못 아시는 듯 하네요.
결과가 이렇게 나오지 않나요?
0 0
0 0
100 100
0 0
자바에서 클래스 인스턴스 변수는 모두 참조 개념입니다. tricky메써드는 두 Point클래스의 인스턴스를 인자로 받는데 arg1과 arg2는 그 인스턴스의 참조죠. 두 줄의 100대입문은 arg1이 참조하는 인스턴스의 값을 바꿉니다. 그리고 그 아래는 arg1과 arg2가 참조하는 인스턴스를 바꾸는 코드를 넣으셨는데 arg1이나 arg2는 그 메써드 안의 지역변수로 할당이 됩니다. 지역변수의 참조 위치를 바꾸어봐야 메써드 벗어나면 다 사라지죠. 제 국어실력이 모자라 더 자세한 설명이 안 되네요. C를 아시면 포인터 개념에 대입해 생각해 보시면 될 것 같네요.
---------- 시그 *****
저도 세벌식을 씁니다.
M$윈도우즈, 리눅스, 맥 오에스 텐, 맥 오에스 클래식을 모두 엔드유저 수준으로 쓴답니다.
http://psg9.egloos.com
=================
잠못자는 한솔아빠
Call by value(copy)라서 그래요.
자바에서 매개변수는 primitive와 reference 타입 모두 call by value입니다.
따라서 reference가 가리키는 객체의 값을 변경할 수는 있지만 원래 reference 자체의 값을 로컬에서 변경할 수 없는 것이죠.
C#에서는 ref/out 지시자로 그게 가능하더군요.
자바의 경우는 사실
자바의 경우는 사실 call by value다, call by reference다를 구분 짓기 애매합니다..라기보다 별 의미가 없습니다. 엄밀하게 따지면 변수의 값이라는 것은 primitive 아니면 reference이기 때문에 이 값은 늘 call by value로 넘어가는 게 맞습니다만 또 객체의 입장에서 보면 객체는 reference로 넘어가니 call by reference라고 보는 것이 더 실용적(?)인 개념이 되는 거죠. call by reference에서의 reference가 자바의 reference와 다르다지만 so what? 별로 중요한 차이가 아니기 때문에 객체는 그냥 call by reference라고 가르치는 경우도 많습니다.
흔히 call by reference는 무조건 out parameter가 가능한 것..이라고 하기도 하는데 사실 예전에는 C에서 포인터를 인자로 넘기는 것을 call by reference라고 불렀다는 점을 상기한다면 out parameter는 그냥 별도의 개념으로 다루는 것이 맞는 것 같습니다. 이미 현대적인 OOP 언어들에서는 문법적으로 두 개념을 구분하고 있죠.
그래서, 이 문제의 답은 자바가 call by value이기 때문에 안된다..라기보다 자바는 out parameter를 지원하지 않기 때문에 안된다..라고 말하는 것이 좀더 가깝다고 봅니다.
-0-
제 짧은 생각으로는 콘스트럭터는 맨처음 콜 됬을경우에만 셋 하는것 아닌가요?
그리고 기본 적인 거라서 말하면 제가 초보라서 말이 안될지도 모르곘는데...
public class Test {
public static void change(int a[], int b[]){
b=a;
}
public static void main (String [] args) {
int a[] = new int[20];
int b[] = new int[20];
a[0]=1;
change(a, b);
System.out.println(b[0]);
}
}
이렇게 써도 출력되는건 0 아닌가요?
매인 변수값을 바꾸려면
public class Test {
public static void change(int a[], int b[]){
b[0]=a[0];
}
public static void main (String [] args) {
int a[] = new int[20];
int b[] = new int[20];
a[0]=1;
change(a, b);
System.out.println(b[0]);
}
}
이렇게 해줘야 1 이 출력되죠.
자바에서는 어떻게 해야되는지 모르곘네요.
--------------------------------------------------------------------
허접한 페도라 가이드 http://oniichan.shii.org
---------------------------------------------------------------------------------------------------------------
루비 온 레일즈로 만들고 있는 홈페이지 입니다.
http://jihwankim.co.nr
여러 프로그램 소스들이 있습니다.
필요하신분은 받아가세요.
...
public static void tricky(Point arg1, Point arg2){
arg1.x = 100;
arg1.y = 100;
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}
위의 메소드에서
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
는 아무 효력을 발휘하지 못합니다
----------------
agidari.wordpress.com
이렇게 적어보세요.
public static void tricky(Point arg1, Point arg2){
arg2.x = 100;
arg2.y = 100;
}
허접한 페도라 가이드 http://oniichan.shii.org
---------------------------------------------------------------------------------------------------------------
루비 온 레일즈로 만들고 있는 홈페이지 입니다.
http://jihwankim.co.nr
여러 프로그램 소스들이 있습니다.
필요하신분은 받아가세요.
결론은...
{
a---------------> m_a
b---------------> m_b
{
a'--------------> m_a
b'--------------> m_b
스왑
b'--------------> m_a
a'--------------> m_b
}
a----------------> m_a
b----------------> m_b
}
의 모양이 되겠군요...
a' 과 b'을 아무리 swap 해도... a와 b에는 영향을 끼칠 수 없다가 정답이겠죠?
지나가려다가...
저 위의 예는 오래된 고전의 bad swap 그대로입니다. 글쓰신 분도 그것을 알고 여기에 올리셨을 겁니다. 정답에 점수가 올라가 있네요. 그런데 스왑의 여부 보다는 Point 클래스를 저렇게 만들면 말 그대로 딱 뒤통수 맞는거죠.
----
I paint objects as I think them, not as I see them.
atie's minipage
----
I paint objects as I think them, not as I see them.
atie's minipage
음.... Point p = new
음....
Point p = new Point();
p.x = 10;
p.y = 11;
보다
Point p = new Point(10, 11);
이 편하니 이것을 의도하셨던 것이 아닐까요^^.
C에 비유하자면
댓글 달기