1. Pass by value
이번에는 아주 복잡하고 중요한 이야기 입니다. 이 부분은 머리 속에 꼭 넣어 놔야만 합니다. 다음 예제 코드를 보면 callPassByValue()라는 메소드에 int 값으로 10을, String 값으로 b를, MemberDTO의 name을 "Sangmin"으로 선언한 후 passByValue()라는 메소드로 넘겨 주었습니다.
1
2
3
4
5
6
7
8
9
10
11
|
public class MemberDTO {
public String name;
public String phone;
public String email;
MemberDTO(String name){
this.name = name;
}
}
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public class ReferenceTypes{
public void callPassByValue() {
int a = 10;
String b = "b";
MemberDTO member = new MemberDTO("Sangmin");
passByValue(a,b,member);
System.out.println("callByValue method result !!! ");
System.out.println("a="+a);
System.out.println("b="+b);
System.out.println("member.name="+member.name);
}
public void passByValue(int a, String b, MemberDTO member) {
a = 20;
b = "z";
member = new MemberDTO("SungChoon");
System.out.println("passByValue method result !!! ");
System.out.println("a="+a);
System.out.println("b="+b);
System.out.println("member.name="+member.name);
}
public static void main(String[] args) {
ReferenceTypes referType = new ReferenceTypes();
referType.callPassByValue();
}
}
|
|
이 코드의 실행결과를 보면 다음과 같습니다.
passByValue()라는 메소드에서는 int인 a값을 20으로, String인 b의 값을 "z"로, MemberDTO의 member에 name을 "SungChoon"으로 사용하는 생성자를 사용하여 기존 객체를 버리고 새로운 객체를 만들도록 하였습니다.
"Pass by value"는 값만 전달한다는 의미입니다. 메소드의 매개 변수로 넘길 때에는 원래 값은 놔 두고, 전달되는 값이 진짜인 것처럼 보이게 합니다. 그래서, 매개 변수를 받은 메소드에서 그 값을 어떻게 하든 원래의 값은 전혀 바뀌지 않습니다.
기본 자료형은 "무조건" "Pass By Value"로 데이터를 전달합니다. 그리고 참조 자료형도 "Pass By Value"로 데이터를 전달합니다. callPassByValue() 메소드에서 passByValue()메소드를 호출 하고 나서도 메소드에 있는 변수들의 값은 전혀 변함이 없이 그대로 있습니다.
2. Pass by reference
위의 값만 전달하는 것과 달리 객체에 대한 참조(Reference)가 넘어가는 것을 "Pass By Reference"라고 합니다. 다음과 같이 member는 변수의 name을 passByValue() 메소드에서 변경하도록 해당 메소드를 변경해봅시다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
public class ReferenceTypes{
public void callPassByValue() {
int a = 10;
String b = "b";
MemberDTO member = new MemberDTO("Sangmin");
passByValue(a,b,member);
System.out.println("callByValue method result !!! ");
System.out.println("a="+a);
System.out.println("b="+b);
System.out.println("member.name="+member.name);
}
public void passByValue(int a, String b, MemberDTO member) {
a = 20;
b = "z";
//member = new MemberDTO("SungChoon");
member.name = "SungChoon";
System.out.println("passByValue method result !!! ");
System.out.println("a="+a);
System.out.println("b="+b);
System.out.println("member.name="+member.name);
}
public static void main(String[] args) {
ReferenceTypes referType = new ReferenceTypes();
referType.callPassByValue();
}
}
|
|
이제 실행 결과를 봐봅시다.
MemberDTO인 member의 name은 "SungChoon"으로 변경된 것을 확인 할 수 있습니다.
● 모든 기본 자료형과 참조 자료형은 매개 변수로 넘어갈 때 값이 넘어가는 Pass By Value 입니다.
● 참조 자료형 안에 있는 변수들은 매개 변수로 넘어갈 때 참조가 넘어가는 Pass By Reference입니다.
기본 자료형은 무조건 Pass By value이기 때문에 헷갈리지 않지만, 매개 변수로 넘어가는 참조 자료형 자체는 Pass by Value이기는 하나, 그 안에 있는 애들은 Pass By Reference라는 것을 반드시 기억해야 합니다!
여기서 String도 참조 자료형이니 원래 호출한 메소드에 있는 것도 바뀌어야 한다고 생각할 수 있습니다.
1
2
3
4
5
|
String b="b";
b = "z";
String b = new String("b");
b = new String("z");
|
|
"z"를 String 변수 b에 할당하는 위의 2가지 방식은 동일합니다. new를 안 썼을 뿐이지 String은 따옴표로 묶어주어서 기존 변수에 할당 하는 작업 자체가 새로운 객체를 생성하는 것입니다.
1
2
|
String b = "b";
b = b + "z";
|
|
위의 코드도 자바에서는 String은 이렇게 더하기 연산을 하면 기존의 객체는 버리고 새로운 객체를 만듭니다. new를 안썼을 뿐이지 b = "z"와 다름 없습니다.
'Java' 카테고리의 다른 글
[Java] 10. 접근 제어자 (0) | 2019.03.19 |
---|---|
[Java] 9.패키지 (0) | 2019.03.10 |
[Java] 7. 참조 자료형 (0) | 2019.03.03 |
[Java] 6. 배열 (0) | 2019.03.01 |
[Java] 5. switch문 (0) | 2019.03.01 |