: 값에 의한 호출형태로 값을 복사하는 것
public class CallByValue {
public static void main(String[] args) {
int a = 10, b = 20; //step 1, step 2
System.out.println(plus(a, b)); // step 3
System.out.println(a); //10
}
public static int plus(int x, int y) {
x += y; //step 4
return x;
}
}
step 별 메모리 변화
두개의 int형 인자값을 더해서 반환하는 간단한 덧셈 정적 메서드와 이 메서드에 10, 20을 인자값으로 전달하여 반환값을 출력하고 있다.
이 때, 각각의 인자값 10과 20은 기본 타입(primitive type)으로 값은 복사되어 전달되기에 a에 b를 더해줬지만 전혀 영향을 받지 않는다. 그렇기에 plus 메소드 호출 후 다시 a
를 출력해도 결과 값은 10이 나온다.
즉, Call By Value에서는 메서드 호출 시 사용되는 인자의 메모리에 저장되어 있는 값을 복사하여 보낸다.
: 값이 아닌 주소(Address)를 보내면서 전달받은 곳에선 해당 주소를 참조하여 데이터에 접근한다.
public class CallByReference {
public static void main(String[] args) {
Food apple = new Food("사과", 1000);
System.out.println("apple = " + apple);
updatePriceByShelfLife(apple);
System.out.println("apple = " + apple);
}
private static void updatePriceByShelfLife(Food food) {
final Period period = food.getOverShelfLife(LocalDate.of(2021, Month.MAY, 23));
if (!period.isNegative()) {
food.changePrice(food.getPrice() - 500);
}
}
private static class Food {
private String name;
private int price;
private LocalDate shelfLife;
public Food(String name, int price) {
this.name = name;
this.price = price;
shelfLife = LocalDate.of(2021, Month.MAY, 20);
}
public String getName() {
return name;
}
public int getPrice() {
return price;
}
public Period getOverShelfLife(LocalDate targetDate){
return Period.between(shelfLife, targetDate);
}
public void changePrice(int price) {
this.price = Math.max(price, 0);
}
@Override
public String toString() {
return "[name: " + name + ", price: " + price + "]";
}
}
}
⇒ update 메소드 호출 전 : [name: 사과, price: 1000]
⇒ update 메소드 호출 후: [name: 사과, price: 500]
로직의 updatePriceByShelfLife() 정적 메소드를 통해 해당 음식의 유통기한을 검사해 유통기간이 지났을 경우 500원을 깎는 로직이다. 여기서 main 로직에 있는 apple과 updatePriceByShelfLife() 에 인자값으로 전달된 apple은 같은 참조주소를 바라본다.
그렇기에 apple을 매개변수로 받은 정적 메서드 updatePriceByShelfLife에서 apple의 값을 수정하면,
main로직의 apple도 동일하게 가격이 변경되있는 것이다.
위 예제를 보고 생각을 하면 당연히 Call By Reference
라는 생각이 들 수 있지만, 이런 고민을 해 볼 필요가 있다. updatePriceByShelfLife(apple); 이 메서드를 호출하면서 apple을 넘겨줄 때 참조 주소 값을 넘겨주고 매개변수를 받은 메서드측에서도 해당 참조주소를 참조해서 객체를 참조한다.