38. νμ₯ν μ μλ μ΄κ±° νμ μ΄ νμνλ©΄ μΈν°νμ΄μ€ μ¬μ©νκΈ°
μ΄κ±° νμ μ체λ νμ₯ν μ μμ§λ§, μΈν°νμ΄μ€μ κ·Έ μΈν°νμ΄μ€λ₯Ό ꡬννλ κΈ°λ³Έ μ΄κ±° νμ μ ν¨κ» μ¬μ©ν΄ κ°μ ν¨κ³Όλ₯Ό λΌ μ μμ
public interface Operation {
double apply(double x, double y);
}
public enum BasicOperation implements Operation {
PLUS("+") {
public double apply(double x, double y) { return x + y; }
},
MINUS("-") {
public double apply(double x, double y) { return x - y; }
},
TIMES("*") {
public double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
public double apply(double x, double y) { return x / y; }
};
private final String symbol;
BasicOperation(String symbol) {
this.symbol = symbol;
}
@Override public String toString() {
return symbol;
}
}
public enum ExtendedOperation implements Operation {
EXP("^") {
public double apply(double x, double y) { return Math.pow(x, y); }
},
REMAINDER("%") {
public double apply(double x, double y) { return x % y; }
};
private final String symbol;
ExtendedOperation(String symbol) {
this.symbol = symbol;
}
@Override public String toString() {
return symbol;
}
}
β³οΈ ν μ€νΈ
public static void main(String[] args){
double x = Double.parseDouble(args[0]);
double y = Double.parseDouble(args[1]);
test(ExtendedOperation.class, x, y);
}
private static <T extends Enum<T> & Operation> void test(Class<T> opEnumType, double x, double y) {
for(Operation op : opEnumType.getEnumConstants())
System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
}
- opEnumType 맀κ°λ³μμ μ μΈ (<T extends Enum<T> & Operation> Class<T>)
π Class κ°μ²΄κ° μ΄κ±° νμ μΈ λμμ Opertaionμ νμ νμ μ΄μ΄μΌ νλ€λ λ»
public static void main(String[] args){
double x = Double.parseDouble(args[0]);
double y = Double.parseDouble(args[1]);
test(Arrays.asList(ExtendedOperation.values()), x, y);
}
private static void test(Collection<? extends Operation> opSet, double x, double y) {
for(Operation op : opSet)
System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
}
- Class κ°μ²΄ λμ νμ μ μμΌλμΉ΄λ νμ λκΉ
- λ 볡μ‘νκ³ test λ©μλκ° μ΄μ§ λ μ μ°ν΄μ§ π μ¬λ¬ ꡬν νμ μ μ°μ° μ‘°ν©ν΄ νΈμΆ κ°λ₯
- νΉμ μ°μ°μμλ EnumSetκ³Ό EnumMap μ¬μ© λͺ»ν¨
β³οΈ μΈν°νμ΄μ€λ‘ νμ₯ κ°λ₯ν μ΄κ±° νμ λ§λ€κΈ°μ λ¨μ
- μ΄κ±° νμ λΌλ¦¬ ꡬν μμ λΆκ°
- Operation μμμ μ°μ° κΈ°νΈλ₯Ό μ μ₯νκ³ μ°Ύλ λ‘μ§μ΄ BasicOperationκ³Ό ExtendedOperation λͺ¨λμ λ€μ΄κ°μΌλ§ ν¨
- νμ¬λ μ€λ³΅λμ΄ μ μ§λ§, 곡μ νλ κΈ°λ₯μ΄ λ§μμ§λ©΄ κ·Έ λΆλΆμ λ³λμ λμ°λ―Έ ν΄λμ€λ μ μ λμ°λ―Έ λ©μλλ‘ λΆλ¦¬νλ λ°©μμΌλ‘ μ½λ μ€λ³΅μ μ€μ¬μΌ ν¨
39. λͺ λͺ ν¨ν΄λ³΄λ€ μ΄λ Έν μ΄μ μ¬μ©νκΈ°
β³οΈ λͺ λͺ ν¨ν΄μ λ¨μ
- μ€νκ° λλ©΄ μλ¨
- μ¬λ°λ₯Έ νλ‘κ·Έλ¨ μμμμλ§ μ¬μ©λλ¦¬λΌ λ³΄μ¦ν μ μμ
- νλ‘κ·Έλ¨ μμλ₯Ό 맀κ°λ³μλ‘ μ λ¬ν λ§λ ν λ°©λ²μ΄ μμ
π μ΄λ Έν μ΄μ μ΄ ν΄κ²°ν΄μ€
// λ§μ»€ μ΄λ
Έν
μ΄μ
νμ
μ μΈ
import java.lang.annotation.*;
/**
* ν
μ€νΈ λ©μλμμ μ μΈνλ μ΄λ
Έν
μ΄μ
* 맀κ°λ³μ μλ μ μ λ©μλ μ μ©
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test {
}
- μ΄λ Έν μ΄μ μ μΈμ λ€λ μ΄λ Έν μ΄μ = λ©νμ΄λ Έν μ΄μ
- @Retention(RetentionPolicy.RUNTIME) : @Testκ° λ°νμμλ μ μ§λμ΄μΌ νλ€λ νμ
- @Target(ElementType.METHOD) : @Testκ° λ°λμ λ©μλ μ μΈμμλ§ μ¬μ©λμ΄μΌ νλ€κ³ μλ €μ€ π ν΄λμ€ μ μΈ, νλ μ μΈ λ± λ€λ₯Έ νλ‘κ·Έλ¨ μμμ λ¬ μ μμ
// 맀κ°λ³μ νλλ₯Ό λ°λ μ΄λ
Έν
μ΄μ
νμ
import java.lang.annotation.*;
/**
* λͺ
μν μμΈλ₯Ό λμ ΈμΌλ§ μ±κ³΅νλ ν
μ€νΈ λ©μλμ© μ΄λ
Έν
μ΄μ
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExceptionTest {
Class<? extends Throwable> value();
}
public class Sample2 {
@ExceptionTest(ArithmeticException.class)
public static void m1(){
int i = 0;
i = i / i;
}
@ExceptionTest(ArithmeticException.class)
public static void m2(){
int[] a = new int[0];
int i = a[1];
}
@ExceptionTest(ArithmeticException.class)
public static void m3(){ }
}
// λ°°μ΄ λ§€κ°λ³μλ₯Ό λ°λ μ΄λ
Έν
μ΄μ
νμ
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExceptionTest {
Class<? extends Throwable>[] value();
}
@ExceptionTest({ IndexOutOfBoundsException.class, NullPointerException.class })
public static void doublyBad() {
List<String> list = new ArrayList<>();
list.addAll(5, null);
}
- μλ° 8μμλ λ°°μ΄ λ§€κ°λ³μλ₯Ό μ¬μ©νλ λμ μ΄λ Έν μ΄μ μ @Repeatable λ©νμ΄λ Έν μ΄μ μ λ¬λ©΄ λ¨
- @Repeatableμ λ¨ μ΄λ Έν μ΄μ μ λ°ννλ '컨ν μ΄λ μ΄λ Έν μ΄μ 'μ νλ λ μ μνκ³ , @Repeatableμ μ΄ μ»¨ν μ΄λ μ΄λ Έν μ΄μ μ class κ°μ²΄λ₯Ό 맀κ°λ³μλ‘ μ λ¬ν΄μΌ ν¨
- 컨ν μ΄λ μ΄λ Έν μ΄μ μ λ΄λΆ μ΄λ Έν μ΄μ νμ μ λ°°μ΄μ λ°ννλ value λ©μλλ₯Ό μ μν΄μΌ ν¨
- 컨ν μ΄λ μ΄λ Έν μ΄μ νμ μλ μ μ ν 보쑴 μ μ± (@Retention)κ³Ό μ μ©λμ(@Targe)μ λͺ μν΄μΌ ν¨
// λ°λ³΅ κ°λ₯ν μ΄λ
Έν
μ΄μ
νμ
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(ExceptionTestContainer.class)
public @interface ExceptionTest {
Class<? extends Throwable> value();
}
// 컨ν
μ΄λ μ΄λ
Έν
μ΄μ
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExceptionTestContainer {
ExceptionTest[] value();
}
// λ°λ³΅ κ°λ₯ν μ΄λ
Έν
μ΄μ
μ μ©
@ExceptionTest(IndexOutOfBoundsException.class)
@ExceptionTest(NullPointerException.class)
public static void doublyBad() {...}
40. @Override μ΄λ Έν μ΄μ μ μΌκ΄λκ² μ¬μ©νκΈ°
@Overrideλ λ©μλ μ μΈμμλ§ λ¬ μ μκ³ , μμ νμ μ λ©μλλ₯Ό μ¬μ μνμμ μλ―Έν¨
μμ ν΄λμ€μ λ©μλλ₯Ό μ¬μ μνλ €λ λͺ¨λ λ©μλμ @Override μ΄λ Έν μ΄μ μ λ€λ κ² νμ !
π λλΆλΆμ IDEλ μ¬μ μν λ©μλλ₯Ό μ ννλ©΄ μλμΌλ‘ λΆμ¬μ£Όλ―λ‘ μ°Έκ³
π© ꡬ체 ν΄λμ€μμ μμ ν΄λμ€μ μΆμ λ©μλλ₯Ό μ¬μ μν κ²½μ°μλ μ΄λ Έν μ΄μ κ΅³μ΄ λ¬ νμ X
41. μ μνλ €λ κ²μ΄ νμ μ΄λΌλ©΄ λ§μ»€ μΈν°νμ΄μ€ μ¬μ©νκΈ°
π λ§μ»€ μΈν°νμ΄μ€ : μ무 λ©μλλ λ΄κ²¨μμ§ μκ³ , λ¨μ§ μμ μ ꡬννλ ν΄λμ€κ° νΉμ μμ±μ κ°μ§μ νμν΄μ£Όλ μΈν°νμ΄μ€λ‘, μλ‘ μΆκ°νλ λ©μλ μμ΄ λ¨μ§ νμ μ μκ° λͺ©μ μΌ λ μ£Όλ‘ μ¬μ©
β³οΈ λ§μ»€ μΈν°νμ΄μ€κ° λ§μ»€ μ΄λ Έν μ΄μ λ³΄λ€ λμ μ
- λ§μ»€ μΈν°νμ΄μ€λ μ΄λ₯Ό ꡬνν ν΄λμ€μ μΈμ€ν΄μ€λ€μ ꡬλΆνλ νμ μΌλ‘ μ¬μ© κ°λ₯
- μ μ© λμμ λ μ λ°νκ² μ§μ κ°λ₯
// μ§λ ¬ν κ°λ₯ν κ°μ²΄λ₯Ό ꡬλΆνκΈ° μν λ§μ»€ μΈν°νμ΄μ€
public interface SerializableMarker {}
public class User implements SerializableMarker {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class Product implements SerializableMarker {
private String productName;
public Product(String productName) {
this.productName = productName;
}
public String getProductName() {
return productName;
}
}
public class Serializer {
// λ§μ»€ μΈν°νμ΄μ€λ₯Ό νμ
μΌλ‘ λ°μ μ§λ ¬ν κ°λ₯ν κ°μ²΄λ§ μ²λ¦¬
public void serialize(SerializableMarker obj) {
if (obj instanceof User) {
System.out.println("Serializing User: " + ((User) obj).getName());
} else if (obj instanceof Product) {
System.out.println("Serializing Product: " + ((Product) obj).getProductName());
} else {
throw new IllegalArgumentException("Unsupported type for serialization");
}
}
public static void main(String[] args) {
Serializer serializer = new Serializer();
User user = new User("Alice");
Product product = new Product("Laptop");
// μ§λ ¬ν κ°λ₯ν κ°μ²΄λ§ μ²λ¦¬ κ°λ₯
serializer.serialize(user); // Output: Serializing User: Alice
serializer.serialize(product); // Output: Serializing Product: Laptop
// serializer.serialize("Random String"); // μ»΄νμΌ μ€λ₯
}
}
β³οΈ λ§μ»€ μ΄λ Έν μ΄μ μ μ¨μΌνλ κ²½μ°
- ν΄λμ€μ μΈν°νμ΄μ€ μΈμ νλ‘κ·Έλ¨ μμ(λͺ¨λ, ν¨ν€μ§, νλ, μ§μλ³μ λ±)μ λ§νΉν΄μΌν λ
- μ΄λ Έν μ΄μ μ νλ°ν νμ©νλ νλ μμν¬
'Java > π Effective Java' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[π Effective Java] μΌλ°μ μΈ νλ‘κ·Έλλ° μμΉ δΈ (0) | 2024.11.20 |
---|---|
[π Effective Java] μΌλ°μ μΈ νλ‘κ·Έλλ° μμΉ δΈ (0) | 2024.11.19 |
[π Effective Java] μ΄κ±° νμ κ³Ό μ΄λ Έν μ΄μ δΈ (0) | 2024.11.10 |
[π Effective Java] μ λ€λ¦ δΈ (0) | 2024.10.12 |
[π Effective Java] ν΄λμ€μ μΈν°νμ΄μ€ δΈ (1) | 2024.10.06 |