본문 바로가기

JAVA

[ JAVA ] Call by Value vs Call by Reference

 

 

예제 1 - int형 (Call by Value)

 

int a1 = 1;
int a2 = 2;
int a3 = 3;
int a4 = 4;
int a5 = 5;
int a6 = 6;

int b1 = a1;
a1 = 13;

System.out.println(b1);
System.out.println(a1);	
  • 변수 6개를 만들어 값을 저장했고  stack이라는 공간을 차지하게 됨
  • 변수 각각의 메모리 공간을 차지하기 때문에 할당 시 각각 할당됨
  • 그래서 a1 은 13을 출력, b1 은 1을 출력

 

 

예제 2 - String형 (Call by Value)

 

String str1 = "hong";
tring str2 = "kim";
		
String str3 = str1;
str3 = "choi";
		
System.out.println(str3);
System.out.println(str1);
  • String 타입 역시 str3 는 "choi"를 출력, str1은 "hong"을 출력함
  • String은 class이기 때문에 CallByReference로 움직여야 한다. 그러나 String을 할당값으로 선언을 하고 받으면 마치 CallbyValue처럼 움직인다. (only String)
  • class 는 인스턴스화 해서 사용하는게 맞기 때문에 String str = new String(""); 형식으로 인스턴스화 해서 사용하는 것임. 그러나 java 가 처음 나올 때 그 시기에 다른 모든 언어들이 String str = "; 형식으로 쓰고 있었기때문에 저 형식으로 쓸 수 있도록 java에서 허용해주었음
  • String은 원래 call by value가 아닌데 String str = ""; 이라 선언했다면 마치 call by value처럼 움직인다. 
  • String str = new String(""); 이라 선언했다면 call by reference로 움진인다.

 

if(str1 == str2) {
		System.out.println("같다");
			
	}else {
		System.out.println("다르다");
	} 
  • 변수가 가지고 있는 값을 비교해보면 "같다"고 출력되는 것을 볼 수 있다.

 

+ String 인스턴스화 후 비교

String str1 = new String ("홍길동");
String str2 = new String ("홍길동");
		
String str3 = str2;

if(str1 == str2) {

	System.out.println("같다 - object");
			
}else {

	System.out.println("다르다 - object");
        
}

// 다르다 출력
   
if(str2 == str3) {

	System.out.println("같다 - object");
			
}else {

	System.out.println("다르다 - object");
        
}

// 같다 출력
  • if문이 저장되있는 메모리 주소를 비교하는 것으로 인식하여 상단 if문은 "다르다", 하단 if문은 "같다"가 출력됨

 

if(st1.equals(st2)) {
	System.out.println("같다 - value");
}else {
	System.out.println("다르다 - value");
}
  • 두 객체가 가지고 있는 실제 값이 같은지 확인하기 위해서는 equals를 써준다.
  • st1.equals(st2)이라 쓰는 것과 st2.equals(st1)이라 쓰는 것은 같다.

 

String str1 = new String ("홍길동");
String str2 = new String ("홍길동");
		
String str3 = str2;
str3 = "전우치";

if(str1 == str2) {

	System.out.println("같다 - object");
			
}else {

	System.out.println("다르다 - object");
        
}

// 다르다 출력
   
if(str2 == str3) {

	System.out.println("같다 - object");
			
}else {

	System.out.println("다르다 - object");
        
}

// 다르다 출력
  • str3 에 값을 할당하게 되면 str2의 공간을 공유하다가 새로운 공간에 값이 저장되게 된다.
  • 그래서 상단 if문과 하단 if문 모두 "다르다"가 출력된다.

 

 

 

예제 3 - 배열 (Call by Value)

 

int [] arr = new int[6];

arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5;
arr[5] = 6;

int[] arr2 = new int[6];
arr2[0] = arr[0];
arr2[0] = 100;

System.out.println(arr2[0]);
System.out.println(arr[0]);	
  • 배열 자체는 Call by Reference 이나 값 한 개 한 개 같은 경우는 하나의 변수로 값을 저장하여  Call by Value
  • arr2[0] 는 100을 출력, arr[0]은 1을 출력

 

String[] strs = new String[3];

strs[0] = "고";
strs[1] = "강";
strs[2] = "김";
		
strs[0] = strs[1];
strs[0] = "최";
		
System.out.println(strs[0]);
System.out.println(strs[1]);
  • String 타입 역시 하나의 변수를 가지고 할당할 경우 다른 메모리 주소를 가지게 되어 Call by Value로 움직이게 됨.
  • strs[0] 은 "최"를 strs[1]은 "강"을 출력

 

 

예제 4 - 배열 (Call by Reference)

 

int [] arr = new int[6];

arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5;
arr[5] = 6;

int[] arr3 = arr;

arr3[0] = 1234;
		
System.out.println(arr[0]);
System.out.println(arr3[0]);
  • int[] arr3 = arr; 배열 자체를 할당할 경우 배열은 Call by Reference 이기 때문에 두 배열 모두 같은 메모리 주소를 참조하게 됨 
  • arr[0]과 arr3[0] 모두 1234를 출력

 

 

 

예제 5 - 배열 (Call by Reference)

 

String[] strs10 = new String[4];
	
strs10[0] = "홍길동"; 			// call by value
strs10[1] = "전우치";
strs10[2] = "이길동";
strs10[3] = new String("홍길동"); 	// call by reference 
	
if(strs10[0] == strs10[3]) { 
	System.out.println("같다");
}else {	
	System.out.println("다르다");
}
  • "다르다" 출력

 

 

예제 6 - 숫자타입(Call by value)

 

숫자타입은 전부 call by value로 움직인다. 

int aa = 4;
long bb = 4L;
double cc = 4.00;
float dd = 4.00f;

그래서 4개의 값은 모두 같다.