본문 바로가기

JAVA/JAVA 기초

값 전달 방법(callByValue callByReference)과 불변객체

반응형

기본형과 참조형


기본형의 값 전달방법


public class CallByValueSample {

public static void main(String[] args) {

int value =1;

callByValue(value);

System.out.println("호출자" + value);

}

public void callByValue(int value) {

vaule++;

System.out.println("수신자" + value);

}

}


수신자:2

호출자:1


기본형의 값을 전달하는 경우는 수신자에서 값을 변경해도 호출자에 영향을 주지 못한다.



참조형값 전달 방법


public class Entiry {

public int value;

}


public class CallByReferenceSample {

public static void main(String[] args) {

Entity entity = new Entity();

entity.value = 1;

callByReference(entity);

System.out.println("호출자" + entity.value);

}

public void callByReference(Entity entity) {

entity.value++;

System.out.println("수신자" + entity.value);

}

}


수신자:2

호출자:2


참조형의 경우 객체 자체가 아닌 객체에 대한 '참조'를 나타내는 값을 전달한다.


참조형의 값 전달의 경우 호출자의 값이 변하는 것은 인수의 객체에 대한 조작을 하는 경우이다.

인수에 다른값(참조)을 할당할 경우에는 호출자의 값이 변경되지 않는다.


public void callByReference(Entity entity) {

entity = new Entity();

entity.value =2;

System.out.println("수신자" + entity.value);

}


수신자:2

호출자:1


인수에 다른 객체를 할당하면 참조 그 자체가 교체되어 이후에는 새로운 객체로의 조작이 된다.

인수에 객체를 전달했을 때 그 메서드 내에서의 변경이 호출자에도 영향을 준다.

따라서 객체를 메서드의 인수에 전달할 때는 메서드 안에서 값이 변하는지에 대한 여부를 명확히 해야 한다.


규칙

- 원칙적으로 인수 객체의 수정은 피한다.

- 반환값이 void의 경우 인구 객체를 수정해도 좋다.

- 반환값이 void 아닌경우 인수 객체를 변경해서는 안된다.


반환값이 존재하는 경우 인수도 변경되는 것은 상상하기 어렵기 때문이다.

호출에 영향을 미치는지 여부는 Javadoc 주석 등에서 명시적으로 언급하는 것이 좋다.



불변객체 클래스

객체 자체의 값을 변경할 수 없도록 하는 것이 불변객체클래스이다.

Integer등의 래퍼형 클래스와 String클래스, 자바8에서 추가된 Date and Time API의 클래스는 불변 객체 클래스

불변객체클래스로 생성된 객체를 이뮤터블 객체(Immutable Object)

모든 메서드에서 객체 자신의 값을 바꾸지 않으며 조작한 결과는 메서드의 반환값으로 반환하고 있다.


String text = "abcd";

text += "efc";

System.out.println(text);

=> "abcdefg"


String text ="abc";

String text2 = text + "efg";

text = text2;

System.out.println(text);




Integer number = 1;

number++;

System.out.println(number);

=> 2


Integer number = 1;

int number2 = number.intValue();

number2++;

number = Integer.valueOf(number2);

System.out.println(number);


String 및 Integer 클래스의 연산은 연산마다 객체의 생성이 필요해 성능이 나쁘기 때문에 빈번한 연산이 필요한 경우에는 이러한 클래스의 사용을 피하는 것이 좋다.


변경가능 클래스

변경가능(Mutable)

StringBuilder클래스 여러 스레드에서 안전하게 값의 변경과 취득할 수 있는 AtomicInteger 클래스는 객체 자신의 값을 변경할 수 있는 메서드가 있다.


StringBuilder text = new StringBuilder("abcd");

System.out.println(text);

text.append("efg");

System.out.println(text);


AtomicInteger number = new AtomicInteger(1);

System.out.println(number);

number.incrementAndGet();

System.out.println(number);


객체 자신의 값을 변경하는 메서드가 '하나라도' 존재하는경우, 그 클래스는 변경 가능 클래스로 간주될 수 있다.

변경가능 클래스는 메서드의 인수에 객체를 전달했을 때 호출된 곳에서 값을 변경하면 호출한 곳에도 그 영향이 반영된다.


public void someMethod() {

StringBuilder text = new StringBuilder("abcd");

AtomicInteger number = new AtomicInteger(1);

write(text, number);

System.out.println( text + ", "+number);

}


public static void write(StringBuilder text, AtomicInteger number) {

text.append("efg");

number.incrementAndGet();

}



불변 객체 클래스가 좋은 이유는 의도하지 않는 변경에 의한 버그를 일으키지 않으며, 값이 변하지 않는다는 안정감을 가질수 있다.

인수가 변경가능성이 있다면 호출된 메서드 안에서 변경되면 곤란한 경우 객체를 복사하여 인수로 전달할 필요가 있다.

불변 객체 클래스라면 그런 걱정없이 코딩이 가능하다.

하지만 불변 객체 클래스의 경우 객체가 대량으로 생성되는 단점이 있다.


객체의 생성이 몇 개 정도라면 그다지 걱정할 필요는 없다.

하지만 반복되는 루프의 처리 안에 있는 경우는 성능에 미치는 영향은 무시할 수 없다.

루프 처리 안에서 불변 객체 클래스의 값이 변경되는 것은 피하는 것이 좋다.

출처: 자바 마스터북

반응형

'JAVA > JAVA 기초' 카테고리의 다른 글

객체의 라이프 사이클  (0) 2018.10.25
가시성  (0) 2018.10.25
문자열관련  (0) 2018.10.22
예외 관련  (0) 2018.10.21
자바 컬렉션관련  (0) 2018.10.13