
1. ๊ธฐ๋ณธํ๊ณผ ์ฐธ์กฐํ์ ๊ณต์
์๋ฐ์ ๋ฐ์ดํฐ ํ์ ์ ๊ฐ์ฅ ํฌ๊ฒ ๋๊ฐ์ง๋ก ๊ตฌ๋ถํ๋ฉด ๊ธฐ๋ณธํ๊ณผ ์ฐธ์กฐํ์ด ์๋ค.
๊ธฐ๋ณธํ์ ํ๋์ ๊ฐ์ ์ฌ๋ฌ ๋ณ์์์ ์ ๋๋ก ๊ณต์ ํ์ง ์๋๋ค.
์ฐธ์กฐํ์ ํ๋์ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐ๊ฐ์ ํตํด ์ฌ๋ฌ ๋ณ์์์ ๊ณต์ ํ ์ ์๋ค.
์๋ฅผ ๋ค์ด ๊ธฐ๋ณธํ์์๋
int a = 10;
int b = a; // a->b ๊ฐ ๋ณต์ฌ ํ ๋์
b= 20; //a๋ ๊ทธ๋๋ก 10์ด๊ณ b๋ง 20์ผ๋ก ๋ฐ๋๋ค.
๋ฐ๋ฉด์ ์ฐธ์กฐํ์์๋
package lang.immutable.address;
public class Address {
private String value;
public Address(String value) {
this.value = value;
}
public void setValue(String value) {
this.value= value;
}
public void getValue() {
return value;
}
@Override
public String toString() {
return "Address{" +
"value= " + value + '\'' +
'}';
}
}
1. public void setValue(String value)
• ์ญํ :
์ด ๋ฉ์๋๋ ํด๋์ค์ ํ๋ value ๊ฐ์ ๋ณ๊ฒฝ(set)ํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
์ฌ์ฉ์๊ฐ ์ ๊ฐ์ ์ ๋ฌํ๋ฉด, ํด๋์ค ๋ด๋ถ์ value ํ๋๊ฐ ํด๋น ๊ฐ์ผ๋ก ์ ๋ฐ์ดํธ๋๋ค.
2. public String getValue()
• ์ญํ :
์ด ๋ฉ์๋๋ ํด๋์ค์ ํ๋ value ๊ฐ์ ์ฝ๊ธฐ(get) ์ํด ์ฌ์ฉ๋๋ค.
ํธ์ถ์๋ ํ์ฌ ๊ฐ์ฒด์ value ๊ฐ์ ๋ฐํ๋ฐ์ ํ์ธํ ์ ์๋ค.
• ํน์ง:
์ด ๋ฉ์๋๋ value ๊ฐ์ ์ธ๋ถ์์ ์ฝ๊ธฐ๋ง ํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค.
package lang.immutable.address;
public class RefMain1_1 {
public static void main(String[] args) {
//์ฐธ์กฐํ ๋ณ์๋ ํ๋์ ์ธ์คํด์ค๋ฅผ ๊ณต์ ํ ์ ์๋ค.
Address a = new Address("์์ธ");
Address b = a;
System.out.println("a = " + a);
System.out.println("b = " + b);
b.setValue("๋ถ์ฐ"); //b์ ๊ฐ์ ๋ถ์ฐ์ผ๋ก ๋ณ๊ฒฝํด์ผํจ
System.out.println("๋ถ์ฐ -> b");
System.out.println("a = " + a); //์ฌ์ด๋ ์ดํํธ ๋ฐ์
System.out.println("b = " + b);
}
}
์ฒ์์๋ `a` , `b` ๋๋ค ์์ธ์ด๋ผ๋ ์ฃผ์๋ฅผ ๊ฐ์ ธ์ผ ํ๋ค๊ณ ๊ฐ์ ํ์.
๋ฐ๋ผ์ `Address b = a` ์ฝ๋๋ฅผ ์์ฑํ๊ณ , ๋ณ์ a, b ๋๋ค ์์ธ์ด๋ผ๋ ์ฃผ์๋ฅผ ๊ฐ์ง๋ค.
์ดํ์ `b` ์ ์ฃผ์๋ฅผ ๋ถ์ฐ์ผ๋ก ๋ณ๊ฒฝํ๋ค.
๊ทธ๋ฐ๋ฐ ์คํ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด b ๋ฟ๋ง ์๋๋ผ a์ ์ฃผ์๋ ํจ๊ป ๋ถ์ฐ์ผ๋ก ๋ณ๊ฒฝ๋์ด ๋ฒ๋ฆฐ๋ค.
์คํ ๊ฒฐ๊ณผ
a = Address{value='์์ธ'}
b = Address{value='์์ธ'}
๋ถ์ฐ -> b
a = Address{value='๋ถ์ฐ'}
b = Address{value='๋ถ์ฐ'}
์ฐธ์กฐํ ๋ณ์๋ค์ ๊ฐ์ ์ฐธ์กฐ๊ฐ์ ํตํด ๊ฐ์ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ ์ ์๋ค.
`b = a` ๋ผ๊ณ ํ๋ฉด `a` ์์๋์ฐธ์กฐ๊ฐ `x001` ์๋ณต์ฌํด์ `b` ์์ ๋ฌํ๋ค.
์ฐธ์กฐ๊ฐ์ ๋ณต์ฌํด์ ์ ๋ฌํ๋ฏ๋ก ๊ฒฐ๊ณผ์ ์ผ๋ก `a` , `b` ๋ ๊ฐ์ `x001` ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ๋ค.
2. ๊ณต์ ์ฐธ์กฐ์ ์ฌ์ด๋ ์ดํํธ
์ฌ์ด๋ ์ดํํธ(Side Effect)๋ ํ๋ก๊ทธ๋๋ฐ์์ ์ด๋ค ๊ณ์ฐ์ด ์ฃผ๋ ์์ ์ธ์ ์ถ๊ฐ์ ์ธ ๋ถ์ ํจ๊ณผ๋ฅผ ์ผ์ผํค๋ ๊ฒ์ ๋งํ
๋ค.
์ฌ๊ธฐ์ ์ฐธ์กฐํ ์ฝ๋์์ ์ฌ์ด๋ ์ดํํธ๊ฐ ์ผ์ด๋ฌ๋๋ฐ
์ฐธ์กฐ๊ฐ์ ๊ณต์ ํ๋ ํน์ฑ ๋๋ฌธ์ด๋ค.
b์ ์ฃผ์๊ฐ์ ์์ธ์์ ๋ถ์ฐ์ผ๋ก ๋ณ๊ฒฝํ ์๋์์ง๋ง
a๋ ๊ฐ์ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์ a์ ๊ฐ๋ ๋ถ์ฐ์ผ๋ก ๋ณ๊ฒฝ๋์ด ๋ฒ๋ฆฐ๊ฒ์ด๋ค.
3. ์ฌ์ด๋ ์ดํํธ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด?
a์ b์ ์ธ์คํด์ค๋ฅผ ๋ถ๋ฆฌ์์ผ์ค๋ค.
Address a = new Address("์์ธ");
Address b = new Address("์์ธ");
package lang.immutable.address;
public class RefMain1_2 {
public static void main(String[] args) {
Address a = new Address("์์ธ");
Address b = new Address("์์ธ");
System.out.println("a = " + a);
System.out.println("b = " + b);
b.setValue("๋ถ์ฐ");
System.out.println("๋ถ์ฐ -> b");
System.out.println("a = " + a);
System.out.println("b = " + b);
}
}
์คํ๊ฒฐ๊ณผ
a = Address{value='์์ธ'}
b = Address{value='์์ธ'}
๋ถ์ฐ -> b
a = Address{value='์์ธ'}
b = Address{value='๋ถ์ฐ'}


a ์ b ๋์๋ก ๋ค๋ฅธ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ๋ค.
๋ฐ๋ผ์ b๊ฐ ์ฐธ์กฐํ๋ ์ธ์คํด์ค์ ๊ฐ์ ๋ณ๊ฒฝํด๋ a์๋ ์ํฅ์ ์ฃผ์ง ์๋๋ค.
4. ์ฌ๋ฌ ๋ณ์๊ฐ ํ๋์ ๊ฐ์ฒด๋ฅผ ๊ณต์ ํ๋ ๊ฒ์ ๋ง์ ๋ฐฉ๋ฒ์ ์๋ค.
์ฌ์ด๋ ์ดํํธ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ ๋ฐฉ๋ฒ ๋ฐ์ ์๋ค.
4.1 ๊ฐ์ฒด๋ฅผ ๊ณต์ - ์ด ๋ฐฉ๋ฒ ์์ฒด๋ฅผ ๋ง์ ๋ฐฉ๋ฒ์ ์๋ค.
Address a = new Address("์์ธ");
Address b = a;
4.2 ๊ฐ์ฒด๋ฅผ ๊ณต์ ํ์ง ์์ - a์ b์ ์ธ์คํด์ค ๋ถ๋ฆฌ
Address a = new Address("์์ธ");
Address b = new Address("์์ธ");
์ด์ฒ๋ผ ๋จ์ํ๊ฒ ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํด์, ๊ฐ์ ๊ฐ์ฒด๋ฅผ ๊ณต์ ํ์ง ์์ผ๋ฉด ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋๋ค.
์ง๊ธ๊น์ง์ ๋ด์ฉ์ ์ ๋ฆฌํ์๋ฉด,
๊ธฐ๋ณธํ์ ํญ์ ๊ฐ์ ๋ณต์ฌํด์ ๋์ ํ๊ธฐ ๋๋ฌธ์ ๊ฐ์ด ์ ๋๋ก ๊ณต์ ๋์ง ์๋๋ค.
ํ์ง๋ง ์ฐธ์กฐํ์ ๊ฒฝ์ฐ ์ฐธ์กฐ๊ฐ์ ๋ณต์ฌํด์ ๋์
ํ๊ธฐ ๋๋ฌธ์ ์ฌ๋ฌ ๋ณ์์์ ์ผ๋ง๋ ์ง ๊ฐ์ ๊ฐ์ฒด๋ฅผ ๊ณต์ ํ ์ ์๋ค.
๊ณต์ ํ๋ ๊ฒ์ด ์ง๊ธ๊ณผ ๊ฐ์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ๋ง๋๋ ์์ธ์ธ ๊ฒ์ด๋ค.
5. ์ฌ์ด๋ ์ดํํธ๊ฐ ์์ธ์ธ ๊ฒ์ ์ฐพ๊ธฐ ์ด๋ ค์ด ์ํฉ
package lang.immutable.address;
public class RefMain1_3 {
public static void main(String[] args) {
Address a = new Address("์์ธ");
Address b = a;
System.out.println("a = " + a);
System.out.println("b = " + b);
change(b, "๋ถ์ฐ");
System.out.println("a = " + a);
System.out.println("b = " + b);
}
private static void change(Address address, String changeAddress) {
System.out.println("์ฃผ์ ๊ฐ์ ๋ณ๊ฒฝํฉ๋๋ค -> " + changeAddress);
address.setValue(changeAddress);
}
}
์คํ๊ฒฐ๊ณผ
a = Address{value='์์ธ'}
b = Address{value='์์ธ'}
์ฃผ์ ๊ฐ์ ๋ณ๊ฒฝํฉ๋๋ค -> ๋ถ์ฐ
a = Address{value='๋ถ์ฐ'}
b = Address{value='๋ถ์ฐ'} ```
change() ๋ฉ์๋๋ก ์ธ์คํด์ค value๊ฐ์ ๋ณ๊ฒฝํ๋ ๊ฒฝ์ฐ ๊ฒฝ๋ก์ ๊ณผ์ ์ด ์ถ๊ฐ๋์ด์ ๋ณ๊ฒฝ๋ ์ด์ ๋ฅผ ์ฐพ๊ธฐ๊ฐ ์ด๋ ค์์ง๋ค.
6. ๋ถ๋ณ ๊ฐ์ฒด - ๋์
๋ฌธ์ ์ ์ง์ ์ ์ธ ์์ธ์ ๊ณต์ ๋ ์ ์๋ ๊ฐ์ฒด์ ๊ฐ์ ์ด๋์ ๊ฐ ๋ณ๊ฒฝํ๊ธฐ ๋๋ฌธ์ด๋ค.
๊ฐ์ฒด์ ์ํ(๊ฐ์ฒด ๋ด๋ถ์ ๊ฐ, ํ๋, ๋ฉค๋ฒ ๋ณ์)๊ฐ ๋ณํ์ง ์๋ ๊ฐ์ฒด๋ฅผ ๋ถ๋ณ ๊ฐ์ฒด(Immutable Object)๋ผ ํ๋ค.
package lang.immutable.address;
public class ImmutableAddress {
private final String value;
public ImmutableAddress(String value) {
this.value = value;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return "Address{" +
"value='" + value + '\'' +
'}'
}
}
๋ด๋ถ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ์๋๋ค. ๋ฐ๋ผ์ value ์ ํ๋๋ฅผ final๋ก ์ ์ธํ๋ค.
๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ setValue()๋ฅผ ์ ๊ฑฐํ๋ค.
์ด ํด๋์ค๋ ์์ฑ์๋ฅผ ํตํด์๋ง ๊ฐ์ ์ค์ ํ ์ ์๊ณ , ์ดํ์๋ ๊ฐ์ ๋ณ๊ฒฝํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ค.
package lang.immutable.address;
public class RefMain2 {
public static void main(String[] args) {
ImmutableAddress a = new ImmutableAddress("์์ธ");
ImmutableAddress b = a; //์ฐธ์กฐ๊ฐ ๋์
์ ๋ง์ ์ ์๋ ๋ฐฉ๋ฒ์ด ์๋ค.
System.out.println("a = " + a);
System.out.println("b = " + b);
//b.setValue("๋ถ์ฐ"); //์ปดํ์ผ ์ค๋ฅ ๋ฐ์
b = new ImmutableAddress("๋ถ์ฐ");
System.out.println("๋ถ์ฐ -> b");
System.out.println("a = " + a);
System.out.println("b = " + b);
}
}
`ImmutableAddress` ์ ๊ฒฝ์ฐ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ b.setValue()๋ฉ์๋ ์์ฒด๊ฐ ์ ๊ฑฐ๋์๋ค.
์ด์ ImmutableAddress ์ธ์คํด์ค์ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ ๋ฐฉ๋ฒ์ ์๋ค.
ImmutableAddress๋ฅผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์๋ ๊ฐ์ ๋ณ๊ฒฝํ๋ ค๊ณ ์๋ํ๋ค๊ฐ, ๊ฐ์ ๋ณ๊ฒฝํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ค๋ ์ฌ์ค์ ์๊ณ , ์ด ๊ฐ์ฒด๊ฐ ๋ถ๋ณ ๊ฐ์ฒด์ธ ์ฌ์ค์ ๊นจ๋ซ๊ฒ ๋๋ค.
์๋ฅผ ๋ค์ด `b.setValue("๋ถ์ฐ")` ์ ํธ์ถํ๋ ค๊ณ ํ๋๋ฐ, ํด๋น ๋ฉ์๋๊ฐ ์๋ค๋ ์ฌ์ค์ ์ปดํ์ผ ์ค๋ฅ๋ฅผ ํตํด ์ธ์งํ๋ค.
๋ฐ๋ผ์ ์๋ก์ด ImmutableAddress("๋ถ์ฐ") ์ธ์คํด์ค๋ฅผ ์์ฑํด์ b์ ๋์
ํ๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก a , b๋ ์๋ก ๋ค๋ฅธ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ๊ณ , a๊ฐ ์ฐธ์กฐํ๋ ImmutableAddress๋ ๊ทธ๋๋ก ์ ์ง๋๋ค.
์คํ ๊ฒฐ๊ณผ
a = Address{value='์์ธ'}
b = Address{value='์์ธ'}
๋ถ์ฐ -> b
a = Address{value='์์ธ'}
b = Address{value='๋ถ์ฐ'}