Skills/Java

Java - Parameter, Argument

aoaa 2022. 5. 20. 23:35

 Java에서 코드를 작성할 때, Parameter와 Argument라는 것으로 값을 전달하거나 선언을 합니다. 차이점을 한번 알아보겠습니다. 

 

1. Parameter 

 Parameter는 매개변수로 메서드의 입력 변수명입니다. 이는 실제로 메모리에 할당되어 있지 않은 변수로 텅 빈 하나의 공간입니다. 

import java.util.HashSet;
import java.util.Iterator;

class Solution {
    HashSet<Integer>numSet=new HashSet<>();
   
    public boolean isPrime(int num){
        if(num==0 || num==1)
            return false;
        
        int lim=(int)Math.sqrt(num);
        
        for(int i=2; i<=lim; i++)
            if(num%i==0)
                return false;
        return true;
    }
    
    public void recursive(String comb, String others){
        if(!comb.equals(""))
           numSet.add(Integer.valueOf(comb));
            
        for(int i=0; i<others.length(); i++)
            recursive(comb+others.charAt(i), others.substring(0, i)+others.substring(i+1));
            
    }
    
    public int solution(String numbers) {
        int cnt =0;
        recursive("", numbers);
        
        Iterator<Integer> it=numSet.iterator();
        while(it.hasNext()){
            int num=it.next();
            if(isPrime(num))
                cnt++;
        }
        return cnt;
        
        }
}

 설명을 돕고자 코딩테스트의 문제를 하나 복붙해봤습니다.

public boolean isPrime(int num),

public void recursive(String comb, String others),

public int solution(String numbers)라는 메서드 괄호 안의 값을 Parameter라고 합니다.

 한 줄 요약 한다면, 해당 값이 메서드 내에서 어떤 역할을 할지 정의하는 것입니다.

 

2. Argument 

 Argument는 전달인자라는 뜻으로 메서드의 입력 값을 말합니다. Parameter에 대입하는 값으로 실제로 메모리에 할당된 변수입니다. 위에 코드에서 보면, 

recursive("", numbers); 

if(isPrime(num))

 위와 같이 해당 메서드를 호출할 때 전달하는 값에 사용되는 변수를 Argument입니다. 실제 메서드가 호출될 때 매개변수에 담기는 값을 의미하는데, 해당 Argument를 받아 recursive 메서드와 isPrime 메서드가 실행됩니다.

 

3. In Java

 Java에서는 Argument가 Parameter에게 그대로 전달되지 않습니다. argument가 갖고 있는 값을 parameter가 복사해서 들고가게 됩니다. 

 이 때 원시 자료형(Char, byte, int, long, float 등..)을 제외한 모든 자료형이 참조변수로 객체가 살고 있는 주소를 값으로 가지기 때문에 참조 변수끼리 값을 복사한다는 것은 Argument의 주소값을 복사한다는 것을 의미합니다.

 이를 Pass by Value라고 하는데, 복사된 데이터를 전달하여 구성함으로써, 값을 수정하더라도 원본 데이터에는 영향을 주지 않도록 하는 방식입니다.

 

public class Main{

void process(int value) { 	
	cout << "Value passed into function: " << value << endl;
    value = 10; 
    cout << "Value before leaving function: " << value << endl; 
} 

int main() { 
	int someValue = 7; 
	cout << "Value before function call: " << someValue << endl; 
	process(someValue); cout << "Value after function call: " << someValue << endl; 
	return 0; 
	}

]

 위의 process 메서드는 전달받은 int형 값인 value를 10으로 변경하고 있습니다. 실제 출력을 보면

Value before function call: 7 
Value passed into function: 7 
Value before leaving function: 10 
Value after function call: 7

다음과 같습니다. 이는 process 내에서 해당 값을 수정해도, 해당 메서드가 종료되고 나면 원본의 값은 기존의 상태를 유지하고 있습니다. 이를 Pass by Value 방식으로 동작한다고 합니다. 

 

 

4. 동작 방식

 메서드를 호출한다고 하면 Stack 메모리에 함수의 Return Address가 쌓이게 되고, 그 위에 Parameter 등의 값이 쌓이게 됩니다. 처음에 main() 메서드를 호출하기 때문에 main 메서드의 내용이 Stack에 먼저 쌓이고, 그 중 지역변수로 선언한 someValue가 존재할 것입니다. 그 이후 process라는 메서드를 호출하는 상황이라면 Return address가 stack에 쌓이고, 그 다음 Process의 Parameter인 int형 변수 value도 쌓이게 됩니다. 

 

 여기서 main 메서드의 someValue는 그대로 유지된 상태로, 7이라는 value만을 복사하고 새롭게 메모리를 할당합니다. 실제로 main메서드의 somevalue의 주소값은 0x07040이지만, process함수의 Parameter인 value의 주소값은 0x07000입니다. 이는 두 변수는 값만 같다는 것을 알려줍니다.

 

 

 process 메서드로 전달받은 Parameter value에 어떤 값이 더해지고 곱해진 상태로 process 메서드가 종료된다면, process를 위해 할당된 Call Stack이 pop되어 해당 메모리는 모두 소멸됩니다.

 이때문에 process메서드가 종료된 이후 main 메서드에서 somevalue를 재출력해도 7이라는 값을 유지합니다. 

 

 

 

 

 

참고

 

'Skills > Java' 카테고리의 다른 글

Java - 상속과 조합  (0) 2022.05.29
Java - Stack  (0) 2022.05.23
Java new 연산자  (0) 2022.05.10
Scanner & BufferedReader  (0) 2022.05.07
Java 구성 (class, method, instance)  (0) 2022.05.06