-
참조변수에 대한 작은 오해개발/자바 2020. 3. 16. 14:33
자바에서 기본 자료형 변수를 만들 때를 제외하고, 객체는 전부 new 연산자를 이용해 동적으로 메모리를 할당한다. new 연산자가 반환하는 것은 내부적으로는 메모리의 주소겠지만 자바에서 개발자는 메모리 주소를 알 수 없고 해싱을 거친 참조값(해시코드)만 확인할 수 있다. 애초에 자바에서는 메모리를 직접 다룰 일이 없다.
참조값은 메모리 주소 정보를 갖고 있기 때문에 C/C++의 포인터와 같다고 봐도 된다. 객체를 매개변수로 넘길 때 해당 객체의 참조값이 전달되므로 함수 내에서 객체의 데이터를 변경하면 외부에서도 바뀐 결과를 확인할 수 있다. 다음의 결과는 Lee가 출력된다. changeName()의 매개변수 student는 지역변수이지만 main()에서 생성한 Student 객체의 참조값을 가지고 있으며, 함수 안에서는 해당 참조값을 통해 데이터에 접근한 것이므로 외부에도 반영이 된다.
public class Student { String name; Student() { name = "Kim"; } }
public class Main { private static void changName(Student student) { student.name = "Lee"; } public static void main(String[] args) { Student student = new Student(); changName(student); System.out.println(student.name); } }
여기에서 작은 오해가 생길 수 있다. 함수에서 매개변수로 받은 객체에 새로운 참조값을 할당하면 외부에도 적용될 수 있다고 생각하는 것. 다음 코드를 보자.
public class Main { private static void changStudent(Student student) { student = new Student(); student.name = "Lee"; } public static void main(String[] args) { Student student = new Student(); changStudent(student); System.out.println(student.name); } }
결과값은 Lee가 아닌 Kim이다. 함수에서 매개변수에 새로운 참조값을 할당하며 반환값이 없다. 외부에서 전달한 참조값을 저장하고 있던 student에 새로운 참조값이 대입되면 기존 참조값은 어느 누구도 접근할 수 없다. 가비지 컬렉터의 수거 대상이 되어 버린다. 매개변수인 student는 스택에 저장되는 지역변수일 뿐이므로 외부에서 접근할 길이 없다. 함수에서 매개변수의 참조값으로 데이터를 변경할 수 있는 것과 지역변수에 새로운 참조값을 할당하는 것은 전혀 다른 문제다. C/C++에서 이 문제를 해결하고 싶다면 매개변수에 이중 포인터를 넘기면 된다.
#include <string> class Student { private: std::string name; public: Student() :name("Kim") {} void setName(std::string name) { this->name = name; } std::string getName() { return name; } }; void changeName(Student** student) { delete *student; *student = new Student(); (*student)->setName("Lee"); } int main() { Student* student = new Student(); printf("%s\n", student->getName().c_str()); changeName(&student); printf("%s\n", student->getName().c_str()); delete student; return 0; }
'개발 > 자바' 카테고리의 다른 글
Dynamic Web Project를 Import한 후 생긴 오류들 (0) 2020.04.25 추상 클래스는 무엇 (0) 2020.03.19 정렬 순서 바꾸기 (0) 2020.03.12 배열 탐색도 연산이다 (0) 2020.03.11 객체의 final 변수 (0) 2020.03.10