Effective Java - Item 1
β μ μ ν©ν 리 λ©μλ(Static Factory Method)λ?
μ€μ§ ν΄λμ€μ μΈμ€ν΄μ€λ§μ λ°ννκΈ° μν΄ μ μλ μ μ λ©μλλ₯Ό μ μ ν©ν 리 λ©μλλΌκ³ νλ€.
μ½λ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
public final class LocalTime implements Temporal, TemporalAdjuster, Comparable<LocalTime>, Serializable { ... public static LocalTime of(int hour, int minute, int second) { HOUR_OF_DAY.checkValidValue(hour); if ((minute | second) == 0) { return HOURS[hour]; // for performance } MINUTE_OF_HOUR.checkValidValue(minute); SECOND_OF_MINUTE.checkValidValue(second); return new LocalTime(hour, minute, second, 0); } ... private LocalTime(int hour, int minute, int second, int nanoOfSecond) { this.hour = (byte) hour; this.minute = (byte) minute; this.second = (byte) second; this.nano = nanoOfSecond; } ... }
κ·Έλ λ€λ©΄ μ μμ±μλ₯Ό νΈμΆνμ§ μκ³ μ μ ν©ν 리 λ©μλλ₯Ό μ¬μ©νλμ§, μ μ ν©ν 리 λ©μλμ μ₯/λ¨μ μ μ 리ν΄λ³΄μ.
μ₯μ
- 첫 λ²μ§Έ, μ΄λ¦μ κ°μ§ μ μλ€.
κ°μ²΄λ₯Ό μμ±μλ‘ νΈμΆν λμλ ν΄λμ€μ 맀κ°λ³μκ° λ§μ μλ‘, κ°μ νμ μ 맀κ°λ³μκ° μ¬λ¬ κ° μ‘΄μ¬ν μλ‘, κ°λ°μλ€μ κ° μμ±μλ€μ΄ μ΄λ€ μλ―ΈμΈμ§ μ½κ² νμ ν μ μλ€. λν, public μμ±μλ νλμ μκ·Έλμ²λ‘ νλλ§ μμ±ν μ μλ€. μλ₯Ό λ€μ΄, νκ΅λ₯Ό μλ―Ένλ ν΄λμ€μ νμκ³Ό μ μλμ΄ μ‘΄μ¬νλ€. μ΄λ νμμ μ΄λ¦μΈ String λ³μλ₯Ό λ°λ μμ±μκ° μ‘΄μ¬νλ€λ©΄ μ μλμ μ΄λ¦μΈ String λ³μλ₯Ό λ°λ μμ±μλ μ€λ₯κ° λ°μνλ€. μ΄λ―Έ νλμ String λ³μλ₯Ό λ°λ μμ±μκ° μ‘΄μ¬νκΈ° λλ¬Έμ λ€λ₯Έ μμ±μκ° νΈμΆλ μ μκΈ° λλ¬Έμ΄λ€. λ°λ©΄ μ μ ν©ν 리 λ©μλμμλ λ©μλλͺ μ μ§μ ν μ μκΈ° λλ¬Έμ ν ν΄λμ€μ μκ·Έλμ²κ° κ°μ μμ±μκ° μ¬λ¬ κ° μ‘΄μ¬νλ κ²½μ°μλ μμ±μλ₯Ό μ μ ν©ν 리 λ©μλλ‘ λ°κΎΈκ³ λ©μλλͺ μΌλ‘ κ°κ°μ νΉμ±μ λνλ΄μ΄ μ¬μ©ν μ μλ€.
μ½λ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
public class School { String studentName; String teacherName; int grade; public School(String studentName) { this.studentName = studentName; } // μλ¬ public School(String teacherName) { this.teacherName= teacherName; } public static School createStudent(String name, int grade) { return new School(name, grede); } public static School createTeacher(String name, int grade) { return new School(name, grede); } public static void main(String[] args) { School student = createStudent("νμ", 3); School teacher = createTeacher("μ μλ", 1); } }
β 맀κ°λ³μμ μ’ λ₯μ κ°μκ° κ°μ§λ§ λ©μλλͺ μΌλ‘ μΈν΄ λ°νλλ μΈμ€ν΄μ€μ λͺ νν ꡬλΆμ΄ κ°λ₯νλ€.
- λ λ²μ§Έ, νΈμΆλ λλ§λ€ μΈμ€ν΄μ€λ₯Ό μλ‘ μμ±νμ§λ μμλ λλ€.
μ£Όλ‘ μ¬μ©λλ λΆλ³ κ°μ²΄κ° μ‘΄μ¬νλ€λ©΄ 미리 μμ±λ μΈμ€ν΄μ€λ₯Ό μΊμ±νμ¬ μ¬νμ©ν¨μΌλ‘μ¨ λΆνμνκ² κ°μ²΄λ₯Ό μμ±ν νμκ° μλ€. λνμ μΌλ‘
Boolean.valueOf(boolean)
λ©μλκ° μλ€.Boolean
ν΄λμ€μμλ TURE, FALSEλ₯Ό μμλ‘ μ μν΄ λκ³valueOf()
λ©μλκ° νΈμΆ λμμ λ κ°μ²΄λ₯Ό μλ‘ μμ±νμ§ μκ³ μ‘΄μ¬νλ μμλ₯Ό λ°νν΄μ€λ€.
μ½λ
1 2 3 4 5 6 7 8 9 10 11
public final class Boolean implements java.io.Serializable, Comparable<Boolean> { public static final Boolean TRUE = new Boolean(true); public static final Boolean FALSE = new Boolean(false); ... public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE); } ... }
β valueOf(b) λ©μλλ₯Ό νΈμΆνλ©΄ μ΄λ―Έ μμ±λμ΄ μλ κ°μ²΄λ₯Ό λ°ννλ€.
- μΈ λ²μ§Έ, λ°ν νμ μ νμ νμ κ°μ²΄λ₯Ό λ°νν μ μλ λ₯λ ₯μ΄ μλ€.
νμ ν΄λμ€λ€μ΄ νλμ μμ ν΄λμ€λ₯Ό μμ λ°λ κ΅¬μ‘°μΈ κ²½μ°μ μμ ν΄λμ€μμλ μ΄λ ν 쑰건μ λ°λΌ νμ ν΄λμ€ κ°μ²΄λ€μ λ°νν μ μλ€. μ΄λ, νμ ν΄λμ€μ ꡬν체λ₯Ό 곡κ°νμ§ μκ³ λ λ°νμ΄ κ°λ₯νκΈ° λλ¬Έμ APIλ₯Ό μκ² μ μ§ν μ μλ€. λνμ μΌλ‘,
java.util.Collections
ν΄λμ€μμλ μμ λΆκ°λ λκΈ°ν λ±μ κΈ°λ₯μ ν¬ν¨νμ¬ μ΄ 45κ°μ μ νΈλ¦¬ν° ꡬν체λ₯Ό μ 곡νλλ° λλΆλΆ μ μ ν©ν 리 λ©μλλ₯Ό ν΅νμ¬ μ»μ μ μλ€.
μ½λ
1 2 3 4 5 6 7
public class Arrays { ... public static <T> List<T> asList(T... a) { return new ArrayList<>(a); } ... }
β java.util.Arrays ν΄λμ€μμ asList() λ©μλλ₯Ό ν΅ν΄ Listμ νμ ν΄λμ€μΈ ArrayListλ₯Ό λ°ννλ€.
- λ€ λ²μ§Έ, μ λ ₯ 맀κ°λ³μμ λ°λΌ λ§€λ² λ€λ₯Έ ν΄λμ€μ κ°μ²΄λ₯Ό λ°νν μ μλ€.
λ¨μν νμ ν΄λμ€λ§μ λ°ννλ κ²μ΄ μλλΌ λ§€κ°λ³μμ λ°λΌμ κ°κ° λ€λ₯Έ νμ ν΄λμ€μ κ°μ²΄λ₯Ό λ°ννλ κ²μ΄ κ°λ₯νλ€. μ΄λ, ν΄λΌμ΄μΈνΈλ μ΄λ€ κ°μ²΄κ° λ°ν λλ μ§μ λν΄μλ μ νμκ° μλ€. μλ₯Ό λ€μ΄
EnumSet
ν΄λμ€μnoneOf()
λ©μλλ universe κ°μ λ°λΌμ λ€λ₯Έ νμ ν΄λμ€λ₯Ό λ°νν΄μ€λ€.
μ½λ
1 2 3 4 5 6 7 8 9 10 11 12 13 14
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E> implements Cloneable, java.io.Serializable { public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) { Enum<?>[] universe = getUniverse(elementType); if (universe == null) throw new ClassCastException(elementType + " not an enum"); if (universe.length <= 64) return new RegularEnumSet<>(elementType, universe); else return new JumboEnumSet<>(elementType, universe); } }
β EnumSet ν΄λμ€μ noneOf() λ©μλλ universeμ length κ°μ΄ 64κ° μ΄νμΌ κ²½μ° RegularEnumSet, μλ κ²½μ°μλ JumboEnumSet κ°μ²΄λ₯Ό λ°νν΄μ€λ€.
- λ€μ― λ²μ§Έ, μ μ ν©ν 리 λ©μλλ₯Ό μμ±νλ μμ μλ λ°νν κ°μ²΄μ ν΄λμ€λ μ‘΄μ¬νμ§ μμλ λλ€.
μ§κΈκΉμ§λ μ΄λ―Έ ꡬνλμ΄ μλ ꡬνμ²΄κ° κΈ°μ€μ΄ λμμ§λ§, μ μ ν©ν 리 λ©μλλ₯Ό νμ©νμ λμ ꡬνλμ΄μμ§ μμ κ°μ²΄μ ν΄λμ€κ° μ‘΄μ¬νμ§ μμλ λλ€. μ΄λ¬ν νΉμ§μ μλΉμ€ μ 곡μ νλ μμν¬(Service Provider Framework) μ κ·Όκ°μ΄ λλ€. μλΉμ€λ₯Ό μ 곡νλ μ 곡μλ μλΉμ€μ ꡬν체μ΄κ³ , μ΄ κ΅¬ν체λ€μ ν΄λΌμ΄μΈνΈμ μ 곡νλ μν μ νλ μμν¬κ° ν΅μ νμ¬ ν΄λΌμ΄μΈνΈλ₯Ό ꡬν체λ‘λΆν° λΆλ¦¬ν΄μ€λ€. μλΉμ€ μ 곡μ νλ μμν¬λ 3κ°μ ν΅μ¬ μ»΄ν¬λνΈλ‘ μ΄λ£¨μ΄μ Έ μλ€.
- μλΉμ€ μΈν°νμ΄μ€ (service interface) : ꡬν체μ λμμ μ μνλ μΈν°νμ΄μ€
- μ 곡μ λ±λ‘ API (provider registration API) : μ 곡μκ° κ΅¬ν체λ₯Ό λ±λ‘νλ API
- μλΉμ€ μ κ·Ό API (service access API) : ν΄λΌμ΄μΈνΈκ° μλΉμ€μ μΈμ€ν΄μ€λ₯Ό μ»μ λ μ¬μ©νλ API
μ΄ λ°μ μ’ μ’ λ€ λ²μ§Έ μ»΄ν¬λνΈμΈ μλΉμ€ μ 곡μ μΈν°νμ΄μ€ (service provider interface) κ° μ°μΈλ€.
ν΄λΉ μΈν°νμ΄μ€κ° μλ€λ©΄ κ° κ΅¬ν체λ₯Ό μΈμ€ν΄μ€λ‘ λ§λ€ λ 리νλ μ μ μ¬μ©ν΄μΌ νλ€.
λνμ μΈ μλΉμ€ μ 곡μ νλ μμν¬λ‘λ JDBC(Java Database Connectivity)κ° μ‘΄μ¬νλ€.
JDBC : javaμμ λ°μ΄ν°λ² μ΄μ€μ μ μν μ μλλ‘ νλ java API
β
Connection
: μλΉμ€ μΈν°νμ΄μ€β
DriverManager.registerDriver
: μ 곡μ λ±λ‘ APIβ
DriverManager.getConnection
: μλΉμ€ λ±λ‘ APIβ
Driver
: μλΉμ€ μ 곡μ μΈν°νμ΄μ€
λ¨μ
- 첫 λ²μ§Έ, μμμ νλ €λ©΄ publicμ΄λ protected μμ±μκ° νμνλ μ μ ν©ν 리 λ©μλλ§ μ 곡νλ©΄ νμ ν΄λμ€λ₯Ό λ§λ€ μ μλ€.
μλ₯Ό λ€μ΄ java.util.Collections ν΄λμ€μ κ²½μ°μλ λͺ¨λ μμ±μκ° privateλ‘ μ μΈλμ΄ μκΈ° λλ¬Έμ java.util.Collectionsλ‘ λ§λ ꡬν체λ μμμ΄ λΆκ°λ₯νλ€. λ€λ§ μ΄λ¬ν μ μ μμλ³΄λ€ μ»΄ν¬μ§μ μ μ¬μ©νλλ‘ μ λνκ³ λΆλ³ νμ μΌλ‘ λ§λ€κΈ° μν΄ μ μ½μ μ§μΌμΌ νλ€λ μ μμ μ€νλ € μ₯μ μ΄ λ μ μλ€.
- λ λ²μ§Έ, μ μ ν©ν 리 λ©μλλ νλ‘κ·Έλλ¨Έκ° μ°ΎκΈ° μ΄λ ΅λ€.
public μμ±μλ API μ€λͺ μμ νμΈν μ μκΈ° λλ¬Έμ νλ‘κ·Έλλ¨Έλ€μ΄ μκΈ° μ½μ§λ§, μ μ ν©ν 리 λ©μλκ°μ κ²½μ°μλ javadocμμλ λ°λ‘ μ 리νμ§ μκΈ° λλ¬Έμ API λ¬Έμλ₯Ό μ μμ±νκ³ λ©μλλͺ μ μλ €μ§ κ·μ½μ λ°λΌ μ§μ΄ νλ‘κ·Έλλ¨Έκ° μκΈ° μ½κ² ν΄μ£Όμ΄μΌ νλ€.
from : 맀κ°λ³μλ₯Ό νλλ₯Ό λ°μ ν΄λΉ νμ μ μΈμ€ν΄μ€λ₯Ό λ°ννλ νλ³ν λ©μλ
β
Date d = Date.from(instant);
of : μ¬λ¬ 맀κ°λ³μλ₯Ό λ°μ μ ν©ν νμ μ μΈμ€ν΄μ€λ₯Ό λ°ννλ μ§κ³ λ©μλ
β
Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING);
valueOf : fromκ³Ό ofμ λ μμΈν λ²μ
β
BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
instance / getInstance : (맀κ°λ³μλ₯Ό λ°λλ€λ©΄) 맀κ°λ³μλ‘ λͺ μν μΈμ€ν΄μ€λ₯Ό λ°ννμ§λ§, κ°μ μΈμ€ν΄μ€μμ 보μ₯νμ§λ μλλ€.
β
StackWalker luke = StackWalker.getInstance(options);
create / newInstance : instance νΉμ getInstanceμ κ°μ§λ§, λ§€λ² μλ‘μ΄ μΈμ€ν΄μ€λ₯Ό μμ±ν΄ λ°νν¨μ 보μ₯νλ€.
β
Object newArray = Array.newInstance(classObject, arrayLen);
getType : getInstanceμ κ°μΌλ, μμ±ν ν΄λμ€κ° μλ λ€λ₯Έ ν΄λμ€μ ν©ν 리 λ©μλλ₯Ό μ μν λ μ΄λ€. βTypeβμ ν©ν 리 λ©μλκ° λ°νν κ°μ²΄μ νμ μ΄λ€.
β
FileStore fs = Files.getFileStore(path);
newType : newInstanceμ κ°μΌλ μμ±ν ν΄λμ€κ° μλ λ€λ₯Έ ν΄λμ€μ ν©ν 리 λ©μλλ₯Ό μ μν λ μ΄λ€. βTypeβμ ν©ν 리 λ©μλκ° λ°νν κ°μ²΄μ νμ μ΄λ€.
β
BufferedReader br = Files.newBufferedReader(path);
type : getTypeκ³Ό newTypeμ κ°κ²°ν λ²μ
β
List<Complaint> litany = Collections.list(legacyLitany);