类型安全与代码复用的平衡艺术,主要解决以下问题:
// 标准容器类示例
public class Box<T> {
private T content;
public void put(T item) {
this.content = item;
}
public T get() {
return content;
}
}
// 使用示例
Box<String> stringBox = new Box<>();
stringBox.put("Hello");
String value = stringBox.get(); // 无需强制转型
// 通用数组交换方法
public class ArrayUtils {
public static <T> void swap(T[] array, int i, int j) {
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
// 使用示例
String[] names = {"Alice", "Bob"};
ArrayUtils.swap(names, 0, 1);
// 数值计算接口
public interface Calculator<T extends Number> {
double calculate(T a, T b);
}
// 具体实现
public class AddCalculator implements Calculator<Double> {
@Override
public double calculate(Double a, Double b) {
return a + b;
}
}
// 同时实现Serializable和Comparable
public class MultiBound<T extends Comparable<T> & Serializable> {
public void sort(List<T> list) {
Collections.sort(list);
}
}
类型 | 语法 | 适用场景 | 写入限制 |
---|---|---|---|
无界通配符 |
| 只读操作 | 不能写入 |
上界通配符 |
| 读取T及其子类对象 | 只能写入null |
下界通配符 |
| 写入T及其父类对象 | 可以写入T对象 |
// 生产者使用extends
public static void processProducers(List<? extends Number> list) {
for (Number n : list) {
System.out.println(n.doubleValue());
}
}
// 消费者使用super
public static void addIntegers(List<? super Integer> list) {
for (int i = 0; i < 5; i++) {
list.add(i);
}
}
// 通过Class对象传递类型信息
public class TypeSafeMap {
private Map<Class<?>, Object> map = new HashMap<>();
public <T> void put(Class<T> type, T instance) {
map.put(type, instance);
}
public <T> T get(Class<T> type) {
return type.cast(map.get(type));
}
}
// 使用示例
TypeSafeMap safeMap = new TypeSafeMap();
safeMap.put(String.class, "Secret");
String value = safeMap.get(String.class);
// 正确创建泛型数组方法
public class ArrayFactory {
@SuppressWarnings("unchecked")
public static <T> T[] createArray(Class<T> type, int size) {
return (T[]) Array.newInstance(type, size);
}
}
// 使用示例
String[] strings = ArrayFactory.createArray(String.class, 10);
public interface BaseDao<T, ID> {
T findById(ID id);
List<T> findAll();
void save(T entity);
void delete(ID id);
}
// 具体实现
public class UserDao implements BaseDao<User, Long> {
// 实现接口方法...
}
public class EventBus {
private Map<Class<?>, List<Consumer<?>>> handlers = new HashMap<>();
public <T> void subscribe(Class<T> eventType, Consumer<T> handler) {
handlers.computeIfAbsent(eventType, k -> new ArrayList<>()).add(handler);
}
@SuppressWarnings("unchecked")
public <T> void publish(T event) {
List<Consumer<?>> consumers = handlers.get(event.getClass());
if (consumers != null) {
consumers.forEach(consumer -> ((Consumer<T>) consumer).accept(event));
}
}
}
// 错误示例
List rawList = new ArrayList();
rawList.add("String");
rawList.add(10); // 编译通过但运行危险
// 修正方案
List<String> safeList = new ArrayList<>();
safeList.add("Hello");
// safeList.add(10); // 编译错误
// 错误示例
T[] array = new T[10]; // 编译错误
// 正确方法
T[] array = (T[]) new Object[10]; // 需配合类型转换
<K, V>
优于<T, U>
)@SuppressWarnings
时添加明确注释public abstract class TypeToken<T> {
private final Type type;
protected TypeToken() {
Type superClass = getClass().getGenericSuperclass();
this.type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
}
public Type getType() {
return type;
}
}
// 使用示例
Type stringType = new TypeToken<String>() {}.getType();
public class GenericReflection {
public static void printTypeParameters(Class<?> clazz) {
TypeVariable<?>[] typeParams = clazz.getTypeParameters();
for (TypeVariable<?> param : typeParams) {
System.out.println("Type parameter: " + param.getName());
for (Type bound : param.getBounds()) {
System.out.println(" Bound: " + bound.getTypeName());
}
}
}
}
// 分析List接口
GenericReflection.printTypeParameters(List.class);
通过合理应用泛型技术,可以显著提升代码的健壮性和可维护性。建议在复杂泛型场景中使用IDE的代码检查功能,并配合单元测试验证类型安全性。随着Java版本的演进(如引入var),泛型的使用方式也在不断优化,需要持续关注语言新特性。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。