Java์์ ๋ถ๋ณ ๊ฐ์ฒด
๐ ๋ถ๋ณ(immutable) ๊ฐ์ฒด๋?
๊ฐ์ฒด ์์ฑ ์ดํ์๋ ๊ฐ์ฒด์ ์ํ๊ฐ ๋ฐ๋์ง ์๋ ๊ฐ์ฒด
๐ ๋ถ๋ณ ๊ฐ์ฒด์ ์ฅ์
1. ์ดํดํ๊ธฐ ์ฝ๊ณ ์์ ์ ์ธ ์๋น์ค ๊ฐ๋ฐ์ ๋์์ด ๋๋ค
2. map, set, cache์ ์ฐ๊ธฐ์ ์ ์ ํ๋ค.
์๋ฅผ ๋ค์ด ์๋์ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ ๋
Set<RGB> myRGBs = new HashSet<>();
RGB green = new RGB(0, 128, 0);
myRGBs.add(green);
RGB invertedGreen = green.invert();
System.out.println(myRGBs.contains(invertedGreen)); //์์: false, ๊ฒฐ๊ณผ: false
System.out.println(myRGBs.contains(green)); //์์: true, ๊ฒฐ๊ณผ: false
RGB greenAgain = new RGB(0, 128, 0);
System.out.println(myRGBs.contains(greenAgain)); //์์: true, ๊ฒฐ๊ณผ: false
public class RGB {
private int r, g, b;
public RGB(int r, int g, int b){
this.r = r; this.g = g; this.b = b;
}
public int hashCode() {
return r << 16 + g << 8 + b;
}
public boolean equals(Object obj) {
RGB o = (RGB) obj;
return r == o.r && g == o.g && b == o.b;
}
//๊ฐ์ฒด์ ์ํ๋ฅผ ๋ฐ๊ฟ์ ํด์์
์ด ์ ๋๋ก ๋์ํ์ง ์๊ฒ๋ง๋๋ ๋ถ๋ถ
public RGB invert() {
r = 255 - r; g = 255 - g; b = 255 - b;
return this;
}
}
์ด๋ฐ ์์ผ๋ก ๋ฐ๊ฟ ํด๊ฒฐํ๋ค.
private final int r, g, b;
...
public RGB invert() {
RGB inv = new RGB(255-r, 255-g, 255-b);
return inv;
}
3. (์ผ๋ฐ์ ์ผ๋ก) thread-safe ํ๋ค.
4. ๋ถ๋ณ ๊ฐ์ฒด๋ฅผ ํ๋๋ก ์ฐ๋ฉด ๋ฐฉ์ด์ ๋ณต์ฌ๋ฅผ ํ ํ์๊ฐ ์๋ค.
→ ๋ชจ๋ ๊ฒ์ ๋ถ๋ณ ๊ฐ์ฒด๋ก ํํํ ์ ์์ง๋ง ๊ฐ๋ฅํ๋ค๋ฉด ๋ถ๋ณ ๊ฐ์ฒด๋ก ํํํ๋ ๊ฒ์ ์ถ์ฒํจ.
Java์ String
String์ Java์ ๋ํ์ ์ธ ๋ถ๋ณ ๊ฐ์ฒด
String easyCode = "์ฌ์ด์ฝ๋"
String sameRef = easyCode;
System.out.println(easyCode == sameRef); //true
easyCode = "๋์ฌ์ด์ฝ๋" //์์ ์๋ก์ด ๋ฌธ์์ด์ ํ ๋นํ๋ค.
System.out.println(easyCode == sameRef); //false
๐ Java์์ ๋ถ๋ณ ๊ฐ์ฒด ๋ง๋ค๊ธฐ
1. ์์ฑ์๋ฅผ ์ ์ธํ๊ณ ์ํ๋ฅผ ๋ฐ๊ฟ๋งํ ๋ฉ์๋๋ฅผ ๋ชจ๋ ์ ๊ฑฐ
2. ๋ชจ๋ ํ๋๋ฅผ private final๋ก ์ง์
ํด๋์ค๋ฅผ ์๋์ ๊ฐ์ด ๋ถ๋ณ ๊ฐ์ฒด๋ก ๋ง๋ค์ด๋
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
๋ค์๊ณผ ๊ฐ์ด getter๋ฅผ ์ฌ์ ์ํ์ฌ ๊ฐ๋ณ ๊ฐ์ฒด์ธ ๊ฒ์ฒ๋ผ ๋ง๋ค ์ ์์
public class NewPerson extends Person {
private String newName;
public NewPerson(String name) {
super(name);
newName = name;
}
public void setName(String name) {
this.newName = name;
}
public String getName() {
return this.newName;
}
}
Person person = new NewPerson("messi");
System.out.println(person.getName()); //messi
NewPerson newPerson = (NewPerson) person;
newPerson.setName("wow");
System.out.println(person.getName()); //wow
→ 3. ์๋ ํด๋์ค์ ๋ฉ์๋ override ๊ธ์ง. ์ฆ, ํด๋์ค ์์ ๊ธ์ง
- ํด๋์ค ์์ final ํค์๋๋ฅผ ๋ถ์ด๊ฑฐ๋
- ์์ฑ์์ ์ ๊ทผ์ ์ด์๋ฅผ public → private์ผ๋ก ๋ฐ๊พธ๊ณ static factory method๋ฅผ ํตํด ๊ฐ์ฒด๋ฅผ ์์ฑ
๋ง์ฝ ๊ฐ์ฒด์ ํ๋ ์ค์ ๊ฐ๋ณ(mutable) ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ ํผ๋ฐ์ค๊ฐ ์๋ค๋ฉด?
→ 4. mutable ๊ฐ์ฒด์ ๋ ํผ๋ฐ์ค๋ฅผ ๊ณต์ ํด์ ์ฌ์ฉํ์ง ๋ง ๊ฒ.
์ด๋ฅผ ์ํด ๋ฐฉ์ด์ ๋ณต์ฌ๋ฅผ ํ์ฉ
public final class Person {
private final String name;
private final RGB rgb; //RGB is mutable. RGB๊ฐ ๊ฐ๋ณ ๊ฐ์ฒด์ธ ๊ฒฝ์ฐ๋ฅผ ๊ฐ์
public Person(String name, RGB rgb) {
this.name = name;
this.rgb = new RGB(rgb.r, rgb.g, rgb.b); //๋ฐฉ์ด์ ๋ณต์ฌ
//this.rgb = rgb; RGB๊ฐ ๊ฐ๋ณ ๊ฐ์ฒด์๋ค๋ฉด ๋ฐฉ์ด์ ๋ณต์ฌ ํ์ ์์.
}
public String getName() {
return name;
}
public RGB getRGB() {
//return rgb; RGB๊ฐ ๊ฐ๋ณ ๊ฐ์ฒด์๋ค๋ฉด ๋ฐฉ์ด์ ๋ณต์ฌ ํ์ ์์.
return new RGB(rgb.r, rgb.g, rgb.b); //๋ฐฉ์ด์ ๋ณต์ฌ
}
}
RGB green = new RGB(0, 128, 0);
Person person = new Person("messi", green);
System.out.println(person.getRGB().g); //128
RGB myRGB = person.getRGB();
myRGB.g = 0;
System.out.println(person.getRGB().g); //128
๐ List๋ฅผ ํ๋๋ก ๊ฐ์ง๋ค๋ฉด?
List์ List์ ์๋ mutable ๊ฐ์ฒด ๋ชจ๋ ๋ฐฉ์ด์ ๋ณต์ฌ๋ฅผ ํด์ผํ๋ค.
public final class Person {
private final String name;
private final List<RGB> rgbs; //RGB is mutable
public Person(String name, List<RGB> rgbs) {
this.name = name;
this.rgbs = copy(rgbs);
}
public String getName() {
return name;
}
public List<RGB> getRGBs() {
return copy(rgbs);
}
private List<RGB> copy(List<RGB> rgbs) {
List<RGB> cps = new ArrayList<RGB>();
rgbs.forEach(o -> cps.add(new RGB(o.r, o.g, o.b)));
return rgbs;
//๋ง์ฝ RGB๊ฐ immutable ๊ฐ์ฒด์๋ค๋ฉด rgb๋ฅผ ์์ ๋ณต์ฌํด๋ ๊ด๊ณ์์ผ๋ฏ๋ก ์๋์ ๊ฐ์ด ์ฒ๋ฆฌ
//return new ArrayList<>(rgbs);
//๋๋ ์์ฑ์์์
//this.rgbs = Collections.unmodifiableList(rgbs); ๋ก ์ฒ๋ฆฌํ๋ฉด return rgbs;๋ก ๋ฐ๋ก return
}
}
immutable์ ๋ฏธ๋ฌํ ์๋ฏธ ์ฐจ์ด
์ธ๋ถ์ ๋ ธ์ถ๋๋ ์ํ ์ ๋ณด๋ immutableํ์ง๋ง ๋ด๋ถ์์๋ง ๊ด๋ฆฌ๋๋ ์ํ๋ mutableํ ๊ฒฝ์ฐ์๋ immutable ๊ฐ์ฒด๋ผ๊ณ ๋ถ๋ฅด๊ธฐ๋ ํ๋ค. ์ด๋ฐ ๊ฒฝ์ฐ์๋ immutable ๊ฐ์ฒด๋ thread-safeํ์ง ์์ ์ ์์.
ํ์ด์ฌ์์๋ mutableํ ํ๋๋ฅผ ๊ฐ์ง immutable ํด๋์ค๋ immutableํ ๊ฐ์ฒด๋ผ๊ณ ์ ์ํจ.
์ถ์ฒ: https://www.youtube.com/watch?v=EOGOJdBy2Rg&list=PLcXyemr8ZeoT-_8yBc_p_lVwRRqUaN8ET&index=27