[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item17. λ³€κ²½ κ°€λŠ₯성을 μ΅œμ†Œν™” ν•˜λΌ. (λΆˆλ³€ 클래슀)

2023. 2. 27. 16:35ㆍJAVA/Effective JAVA

728x90

 

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item17. λ³€κ²½ κ°€λŠ₯성을 μ΅œμ†Œν™”ν•˜λΌ. 

 

 

λΆˆλ³€ ν΄λž˜μŠ€λž€? 

: κ°„λ‹¨νžˆ λ§ν•΄μ„œ κ·Έ μΈμŠ€ν„΄μŠ€μ˜ λ‚΄λΆ€ 값을 λ³€κ²½ν•  수 μ—†λŠ” 클래슀λ₯Ό λ§ν•œλ‹€. 

λΆˆλ³€ μΈμŠ€ν„΄μŠ€μ— κ°„μ§λœ μ •λ³΄λŠ” κ³ μ •λ˜μ–΄μ„œ 객체가 νŒŒκ΄΄λ˜λŠ” μˆœκ°„κΉŒμ§€ μ ˆλŒ€ 달라지지 μ•ŠλŠ”λ‹€. 

μžλ°”μ—μ„œ λΆˆλ³€ν΄λž˜μŠ€λŠ” String, BigInteger, BigDeciaml 등이 μžˆλ‹€. 

 

λΆˆλ³€ ν΄λž˜μŠ€λŠ” κ°€λ³€ ν΄λž˜μŠ€λ³΄λ‹€ μ„€κ³„ν•˜κ³  κ΅¬ν˜„ν•˜κ³  μ‚¬μš©ν•˜κΈ° μ‰¬μš°λ©°, 였λ₯˜κ°€ 생길 여지도 적고 훨씬 μ•ˆμ „ν•˜λ‹€. 

 

 

λΆˆλ³€ 클래슀 λ§Œλ“œλŠ” 5가지 κ·œμΉ™ πŸ‘Ύ

public final class PhoneNumber // 클래슀λ₯Ό ν™•μž₯ν•  수 없도둝 ν•œλ‹€.
{
   private final short areaCode, prefix, lineNum; // λͺ¨λ“  ν•„λ“œλ₯Ό final둜 μ„ μ–Έ, λͺ¨λ“  ν•„λ“œλŠ” private으둜 μ„ μ–Έ
   
   public PhoneNumber(short areaCode, short prefix, short lineNum)
   {
      this.areaCode = areaCode;
      this.prefix = prefix;
      this.lineNum = lineNum;
   }
   
   public short getAreaCode()
   {
      return areaCode;
   }
   
   public short getPrefix()
   {
      return prefix;
   }
   
   public short getLineNum()
   {
      return lineNum;
   }
}

- 객체의 μƒνƒœλ₯Ό λ³€κ²½ν•˜λŠ” λ©”μ„œλ“œ(λ³€κ²½μž)λ₯Ό μ œκ³΅ν•˜μ§€ μ•ŠλŠ”λ‹€.

: setter λ“±μ˜ μˆ˜μ •μžλ₯Ό μ œκ³΅ν•˜μ§€ μ•ŠλŠ”λ‹€. 

 

- 클래슀λ₯Ό ν™•μž₯ν•  수 없도둝 ν•œλ‹€. 

: 클래슀λ₯Ό final둜 μ„ μ–Έν•΄μ„œ 상속을 막아 ν•˜μœ„ ν¬λž˜μŠ€μ—μ„œ λΆ€μ£Όμ˜ν•˜κ²Œ ν˜Ήμ€ λ‚˜μœ μ˜λ„λ‘œ 객체의 μƒνƒœλ₯Ό λ³€ν•˜κ²Œ λ§Œλ“œλŠ” μ‚¬νƒœλ₯Ό 막도둝 ν•œλ‹€. 

 

- λͺ¨λ“  ν•„λ“œλŠ” final둜 μ„ μ–Έν•œλ‹€. 

: μ‹œμŠ€ν…œμ΄ κ°•μ œν•˜λŠ” μˆ˜λ‹¨μ„ μ΄μš©ν•΄μ„œ μ„€κ³„μžμ˜ μ˜λ„λ₯Ό λͺ…ν™•ν•˜κ²Œ λ“œλŸ¬λ‚΄λŠ” 방법이닀. μƒˆλ‘œ μƒμ„±λœ μΈμŠ€ν„΄μŠ€λ₯Ό 동기화 없이 λ‹€λ₯Έ μŠ€λ ˆλ“œλ‘œ 건넀도 λ¬Έμ œμ—†μ΄ λ™μž‘ν•˜κ²Œλ” 보μž₯ν•˜λŠ”λ°λ„ ν•„μš”ν•˜λ‹€. 

 

- λͺ¨λ“  ν•„λ“œλ₯Ό private둜 μ„ μ–Έν•œλ‹€. 

: ν•„λ“œκ°€ μ°Έμ‘°ν•˜λŠ” κ°€λ³€ 객체λ₯Ό ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ 직접 μ ‘κ·Όν•΄μ„œ μˆ˜μ •ν•˜λŠ” 일을 막아쀀닀. 

 

public class Address
{
   private String zipCode;
   private String street;
   private String city;
   
   public String getZipCode()
   {
      return zipCode;
   }
   
   public void setZipCode(String zipCode)
   {
      this.zipCode = zipCode;
   }
   
   public String getStreet()
   {
      return street;
   }
   
   public void setStreet(String street)
   {
      this.street = street;
   }
   
   public String getCity()
   {
      return city;
   }
   
   public void setCity(String city)
   {
      this.city = city;
   }
}
public final class Person
{
   private final Address address; // addressκ°€ κ°€λ³€ 클래슀라면... Person을 λΆˆλ³€μœΌλ‘œ λ§Œλ“€μ–΄λ„ 값이 λ°”λ€”μˆ˜ μžˆλ‹€.
   
   public Person(Address address)
   {
      this.address = address;
   }
   
   // μžμ‹  μ™Έμ—λŠ” λ‚΄λΆ€μ˜ κ°€λ³€ μ»΄ν¬λ„ŒνŠΈμ— μ ‘κ·Όν•  수 없도둝 ν•œλ‹€.
	public Address getAddress()
	 {
	    return address;
	 }
   
   
   public static void main(String[] args)
   {
      Address seattle = new Address();
      seattle.setCity("Seattle");
      
      Person person = new Person(seattle);
      Address redmond = person.getAddress(); // μžμ‹  μ™Έμ—λŠ” λ‚΄λΆ€μ˜ κ°€λ³€ μ»΄ν¬λ„ŒνŠΈμ— μ ‘κ·Όν•  수 없도둝 ν•œλ‹€.
      redmond.setCity("Redmond");
      
      System.out.println("person.address.getCity() = " + person.address.getCity());
      
   }
}

- μžμ‹  μ™Έμ—λŠ” λ‚΄λΆ€ κ°€λ³€ μ»΄ν¬λ„ŒνŠΈμ— μ ‘κ·Όν•  수 없도둝 ν•œλ‹€. 

: AddressλŠ” κ°€λ³€ μ»΄ν¬λ„ŒνŠΈλΌμ„œ 아무리 Person을 λΆˆλ³€ 객체둜 λ§Œλ“ λ‹€κ³  ν•˜λ”λΌλ„ getAddressλ₯Ό ν†΅ν•΄μ„œ μˆ˜μ •ν•  수 μžˆλ‹€. 

λ”°λΌμ„œ ν΄λž˜μŠ€μ— κ°€λ³€ 객체λ₯Ό μ°Έμ‘°ν•˜λŠ” ν•„λ“œκ°€ ν•˜λ‚˜λΌλ„ μžˆλ‹€λ©΄ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ κ·Έ 객체의 μ°Έμ‘°λ₯Ό 얻을 수 없도둝 ν•΄μ•Ό ν•œλ‹€. 

이런 ν•„λ“œλŠ” μ ˆλŒ€ ν΄λΌμ΄μ–ΈνŠΈκ°€ μ œκ³΅ν•œ 객체 μ°Έμ‘°λ₯Ό κ°€λ¦¬ν‚€κ²Œ ν•΄μ„œλŠ” μ•ˆλ˜λ©°, μ ‘κ·Όμž λ©”μ„œλ“œκ°€ κ·Έ ν•„λ“œλ₯Ό κ·ΈλŒ€λ‘œ λ°˜ν™˜ν•΄μ„œλ„ μ•ˆλœλ‹€!!

public final class Person
{
   private final Address address; // addressκ°€ κ°€λ³€ 클래슀라면... Person을 λΆˆλ³€μœΌλ‘œ λ§Œλ“€μ–΄λ„ 값이 λ°”λ€”μˆ˜ μžˆλ‹€.
   
   public Person(Address address)
   {
      this.address = address;
   }
   
   // μžμ‹  μ™Έμ—λŠ” λ‚΄λΆ€μ˜ κ°€λ³€ μ»΄ν¬λ„ŒνŠΈμ— μ ‘κ·Όν•  수 없도둝 ν•œλ‹€.
// public Address getAddress()
// {
//    return address;
// }
   
   // μžμ‹  μ™Έμ—λŠ” λ‚΄λΆ€μ˜ κ°€λ³€ μ»΄ν¬λ„ŒνŠΈμ— μ ‘κ·Όν•  수 없도둝 ν•œλ‹€. -> getterκ°€ ν•„μš”ν•œ κ²½μš°μ—λŠ” 방어적인 볡사
   public Address getAddress()
   {
      Address copyOfAddress = new Address();
      copyOfAddress.setCity(address.getCity());
      copyOfAddress.setStreet(address.getStreet());
      copyOfAddress.setZipCode(address.getZipCode());
      return copyOfAddress;
   }
   
   public static void main(String[] args)
   {
      Address seattle = new Address();
      seattle.setCity("Seattle");
      
      Person person = new Person(seattle);
      Address redmond = person.getAddress(); // μžμ‹  μ™Έμ—λŠ” λ‚΄λΆ€μ˜ κ°€λ³€ μ»΄ν¬λ„ŒνŠΈμ— μ ‘κ·Όν•  수 없도둝 ν•œλ‹€.
      redmond.setCity("Redmond");
      
      System.out.println("person.address.getCity() = " + person.address.getCity());
      
   }
}

-> 방어적 볡사λ₯Ό μ‚¬μš©ν•΄μ„œ λΆˆλ³€ 객체λ₯Ό μœ μ§€ν•  수 μžˆλ„λ‘ ν•œλ‹€. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90