Java Generics: Type Safety ที่ยืดหยุ่น
#java13 เม.ย. 2569
Generics คืออะไร
Generics (Java 5+) ช่วยให้เขียน code ที่ type-safe และ reusable โดยไม่ต้อง cast หรือเสี่ยง ClassCastException
Generic Class
public class Box<T> {
private T value;
public Box(T value) { this.value = value; }
public T getValue() { return value; }
public void setValue(T value) { this.value = value; }
@Override
public String toString() {
return "Box[" + value + "]";
}
}
// ใช้งาน
Box<String> stringBox = new Box<>("Hello");
Box<Integer> intBox = new Box<>(42);
String s = stringBox.getValue(); // ไม่ต้อง cast
Integer i = intBox.getValue();
Generic Method
public class Utils {
// Generic method
public static <T> List<T> repeat(T item, int times) {
List<T> result = new ArrayList<>();
for (int i = 0; i < times; i++) {
result.add(item);
}
return result;
}
// Multiple type parameters
public static <K, V> Map<V, K> invertMap(Map<K, V> map) {
Map<V, K> result = new HashMap<>();
map.forEach((k, v) -> result.put(v, k));
return result;
}
}
// ใช้งาน
List<String> strings = Utils.repeat("hello", 3);
List<Integer> ints = Utils.repeat(42, 5);
Bounded Type Parameters
// Upper bound - T ต้องเป็น Number หรือ subclass
public static <T extends Number> double sum(List<T> list) {
return list.stream()
.mapToDouble(Number::doubleValue)
.sum();
}
// Multiple bounds
public static <T extends Comparable<T> & Cloneable> T max(T a, T b) {
return a.compareTo(b) >= 0 ? a : b;
}
// ใช้งาน
List<Integer> ints = List.of(1, 2, 3, 4, 5);
double total = sum(ints); // 15.0
Wildcards
// ? extends T - upper bounded wildcard (read-only)
public double sumList(List<? extends Number> list) {
return list.stream().mapToDouble(Number::doubleValue).sum();
}
// ? super T - lower bounded wildcard (write)
public void addNumbers(List<? super Integer> list) {
list.add(1);
list.add(2);
list.add(3);
}
// ? - unbounded wildcard
public void printList(List<?> list) {
list.forEach(System.out::println);
}
Generic Interface
public interface Repository<T, ID> {
Optional<T> findById(ID id);
List<T> findAll();
T save(T entity);
void delete(ID id);
}
public class UserRepository implements Repository<User, Integer> {
@Override
public Optional<User> findById(Integer id) { ... }
// implement other methods
}
สรุป
Generics ทำให้โค้ด type-safe และ reusable ลด boilerplate code และป้องกัน ClassCastException ที่ runtime ควรใช้ generics เมื่อต้องการ class หรือ method ที่ทำงานกับหลาย type ครับ