JAVA: Pass by Value or Reference
자바에서 함수(Method/Function)에 변수를 전달하고자 한다. 이때 전달하는 것은 변수의 값일까 아니면 변수를 참조(Reference)일까. 답은 변수의 값이다. 자바에서는 변수를 전달할 때, 값을 전달(Pass by Value)한다.
간단하게 아래 예제를 보자.
nothing
이라는 변수를 초기화한 후, doSomething()
함수를 호출했다. 이 함수는 매개변수인 something
이라는 변수에 다른 값을 할당한다. doSomething()
함수가 반환된 이후, nothing
의 값은 얼마일까, 답은 여전히 초기 값이 1이다. nothing
이라는 변수의 값이 매개 변수인 something
으로 전달하고, something
에 다른 값을 할당한다 해도 nothing
에는 아무런 영향을 주지 않는다.
그러나 한 가지 주의할 부분이 있다. 바로 객체를 매개 변수로 전달할 때다. 객체를 전달할 때는 객체의 값 전체를 전달하는 것이 아니라 객체를 참조하는 주소 값을 전달한다. 여기서의 주소 값은 객체에 할당된 메모리 주소가 아니라 객체를 참조할 수 있는 어떤 임의 값이라고 생각하자. 객체의 주소 값을 전달하기 때문에 전달 받은 안의 함수에서 객체를 사용할 때 주의해야 한다. 아래 또 다른 예제를 살펴보자.
Everything
이라는 임의의 클래스를 만들고 nothing
이라는 객체를 초기화했다. 그리고 이전 예제처럼 doSomething()
함수를 호출하고 이 함수 내에서 Everything.setThing()
함수를 이용하여 값을 할당했다. doSomething()
함수가 반환된 이후, nothing
의 값은 999로 변경된다. 즉, doSomething()
안에서 전달 받은 변수인 nothing
을 제어한 셈이다. 객체를 매개 변수로 전달할 때, 새로운 객체를 만들고 그 객체의 전달하는 객 체의 값으로 초기화해주지 않는다. 자바에서 매개 변수로 값으로만 전달한다고 생각해서 객체까지 제어할 때 이부분을 간과할 수 있다.
마치며
현업에서 위의 특징 때문에 문제가 발생할 수 있다. 특히 entity 객체일 경우, 트랜잭션 안에서 값을 변경하고 dirty check를 통해 자동으로 데이터베이스까지 값이 변경이 되기 때문이다. Entity에 대한 값 변경이 자유롭다면 유지보수 하기 너무 힘들 것이다. 이러한 부분을 미연에 방지하고자 객체의 값을 변경하는 함수를 엄격하게 제어하는 것은 어떨까.