본문 바로가기
Language/Java

메서드 내에서 포장객체의 값을 변경한다면?

by brother_stone 2023. 4. 25.

pass by value의 원리에 따라, 참조타입을 메서드로 전달하면 인자로 받은 복사본 역시 원본과 같은 주소를 가리킨다. 그래서 메서드 내에서 참조타입을 수정하면 원본이 변경되는 것이다. 

 

pass by value에 대한 내용 참고 - 2023.03.07 - [Language/Java] - Java 메서드 인자 전달 메커니즘

 

Java 메서드 인자 전달 메커니즘

일반적으로 함수의 인자 전달 방법은 pass-by-value와 pass-by-reference로 구분할 수 있다. 먼저 두 방법의 개념을 살펴보고, 자바에서는 어떤 방법을 채택하고 있는지 알아보도록 하자. ** pass-by-value == c

brotherstone.tistory.com

 

 

예시1) Person객체의 필드를 메서드를 통해 수정하는 코드이다.

public class Main {
    public static void main(String[] args) {
        Person person = new Person("John", 25);
        System.out.println("Before method call: " + person.getName()); // 출력: John
        
        modifyPersonName(person);
        
        System.out.println("After method call: " + person.getName()); // 출력: Alice
    }
    
    public static void modifyPersonName(Person p) {
        p.setName("Alice");
    }
}

class Person {
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
}

예시2) StringBuilder변수를 메서드를 통해 수정하는 코드

public class Main {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello");
        System.out.println("Before method call: " + sb); // 출력: Hello
        
        modifyStringBuilder(sb);
        
        System.out.println("After method call: " + sb); // 출력: Hello, World!
    }
    
    public static void modifyStringBuilder(StringBuilder strBuilder) {
        strBuilder.append(", World!");
    }
}

 

위 원리를 적용해 코드를 짜는 것이 익숙해질 때쯤 문득 궁금증이 생겼다. 기본 타입의 포장 객체도 메서드 내에서 수정가능한걸까?

 

코드를 살펴보자.

public static void main(String[] args) {
    Integer number = 5;
    changeValue(number);
    System.out.println(number);
}

public static void changeValue(Integer num) {
    num = 10; // 새로운 Integer 객체를 생성하여 값을 변경
}

int의 포장객체인 number의 값을 changeValue()메서드를 통해 10으로 변경하기 위한 코드이다.

 

하지만 number의 값은 변경되지 않아 출력하면 5가 나온다. 이유가 뭘까?

 

기본 타입의 포장 객체인 Wrapper클래스들은 불변 객체이기 때문이다.

 

String도 마찬가지로 불변 객체이기 때문에 결과는 같다. 

 

결론

메서드에서 불변 객체의 값을 수정하는 것은 원본에 영향을 주지 못한다.

따라서 불변 객체의 값을 변경하기 위해선 새로운 객체를 생성해야하며 메서드의 리턴값을 통해 값을 변경하는 방법이 있다.