2021-03-07
- Call By Value
바로 결론부터 말하자면 자바는 Call By Value와 같은 특징을 가지고 있다. 아래의 코드를 보자.
package StringCallByValue;
public class Main {
public static void stringSwap1(String str1, String str2) {
String temp = str1;
str1 = str2;
str2 = temp;
}
//String 변수 2개를 전달받아 swap 해주는 간단한 메서드 선언
public static void main(String[] args) {
String str1 = "aaa";
String str2 = "bbb";
System.out.println(str1 + " / " + str2);
stringSwap1(str1, str2);
System.out.println(str1 + " / " + str2);
//참조형타입임에도 불구하고 swap 메서드를 사용해도
// 기존에 데이터가 그대로 유지되는 것을 확인할 수 있다.
// String은 Call by Value인 것을 확인할 수 있다.
//이는 매개변수로 받은값과 기존의 변수 str1과 str2가 저장되는 공간이 다르기 때문이다.
}
}
메서드는 간단히 swap을 진행하는 메서드이다. 여기에 str1과 str2의 객체를 넣어 swap을 해준후 해당 값을 출력해주면 신기하게도 str1과 str2는 swap전과 동일한 데이터를 가지고 있다. 이는 메서드 내부에서 사용된 str1과 str2의 공간과 객체 str1과 str2의 저장공간이 서로 다르기 때문이다. 즉 값만 복사되어 매개변수로 들어갈 뿐 실제 객체로 선언된 str1 / str2의 주소와 메서드 내부에서 사용된 str1과 str2의 주소는 서로 다르다는 뜻이다.
- Call By Reference
그렇다면 실제객체에 직접적인 영향을 주기 위해서는 참조 주소를 직접 불러와 변경하여야 하는데, 이를 Call By Reference와 비슷하게 구현하는 방법이 있다.
package StringCallByValue;
public class Main {
public String strA; // 전역변수 선언
public String strB; // 전역변수 선언
public static void stringSwap2(Main s) {
//객체 자체를 매개값으로 받는다.
String temp = s.strA;
s.strA = s.strB ;
s.strB = temp;
}
//String 변수 2개를 전달받아 swap 해주는 간단한 메서드 선언
public static void main(String[] args) {
// 그러면 String을 Call by Reference 처럼 사용하는 방법은 바로
// 변경하고자 하는 타입의 변수를 전역변수로 선언해 주면 된다.
Main str = new Main();
//객체를 생성해준다.
str.strA = "aaa";
str.strB = "bbb";
System.out.println(str.strA + " / " + str.strB);
stringSwap2(str);
// 넘겨준 객체의 주소값이 전달되기 때문에
// 메서드의 로직은 정상적으로 동작하여 서로 swap이 되게된다.
System.out.println(str.strA + " / " + str.strB);
}
}
클래스 객체를 생성해 해당 객체의 필드를 이용하는 방법이다. 해당 객체 필드 간의 데이터를 객체 내부의 메서드로 변경을 해주는 방식을 이용하는 것이다. 이를 통해 메서드 내부에서도 객체를 명시적으로 나타내 주어 같은 필드 값을 참조하게 되며, 이를 통해 swap을 진행하면, 정상적으로 필드 데이터가 변경되는 것을 확인할 수 있다.