https://mp.weixin.qq.com/s/5oePzbAnV04aUOOcpw9VLA

getSuperclass()

返回直接继承的父类(由于编译擦除,没有显示泛型参数)

如果此 Class 表示 Object 类、一个接口、一个基本类型或 void,则返回 null。
如果此对象表示一个数组类,则返回表示该 Object 类的 Class 对象。

getGenericSuperclass()

这个可以用来获取所继承的超类的类型。返回的 Type,表示 Class 对象对应的实体(类、接口、基元类型或 void)的直接超类的 Type。

Type type1 = ArrayList.class.getGenericSuperclass();
System.out.println("ArrayList.class的超类的类型:"+type1.getTypeName());
// 下标0表示第1个参数,若有多个参数可递增
System.out.println("ArrayList.class的超类的泛型参数类型:"+((ParameterizedType)type1).getActualTypeArguments()[0]); 

// 打印结果如下:

// ArrayList.class的超类的类型:java.util.AbstractList<E>
// ArrayList.class的超类的泛型参数类型:E
这个是只能获取直接超类(第一级超类)的类型,如果还需要获取超类的超类的类型,可以加上 getSuperclass()。
Type type1 = ArrayList.class.getSuperclass().getGenericSuperclass();
System.out.println("ArrayList.class的超类的超类的类型:"+type2.getTypeName());
// 下标0表示第1个参数,若有多个参数可递增
System.out.println("ArrayList.class的超类的超类的泛型参数类型:"+((ParameterizedType)type2).getActualTypeArguments()[0]); 

// 打印结果如下:
// ArrayList.class的超类的超类的类型:java.util.AbstractCollection<E>
// ArrayList.class的超类的超类的泛型参数类型:E

getInterfaces()

返回直接实现的接口(由于编译擦除,没有显示泛型参数)

如果此对象表示一个类,则返回值是一个数组,它包含了表示该类所实现的所有接口的对象。数组中接口对象顺序与此对象所表示的类的声明的 implements 子句中接口名顺序一致
如果此对象表示一个接口,则该数组包含表示该接口扩展的所有接口的对象。数组中接口对象顺序与此对象所表示的接口的声明的 extends 子句中接口名顺序一致
如果此对象表示一个不实现任何接口的类或接口,则此方法返回一个长度为 0 的数组
如果此对象表示一个基本类型或 void,则此方法返回一个长度为 0 的数组

getGenericInterfaces()

这个可以用来获取所实现的接口的类型。返回的 Type,表示 Class 对象对应的类或接口所实现的接口的类型数组(因为 JAVA 中类可实现/接口可继承 N 个接口)。

// 下标0表示所实现接口中的第1个
Type type2 = ArrayList.class.getGenericInterfaces()[0];
System.out.println("ArrayList.class实现的第1个接口的类型:"+type2.getTypeName());
System.out.println("返回值type2本身的实际类型:"+type2.getClass());
// 实际类型为ParameterizedTypeImpl的,可以强转,继续获取泛型参数的类型;若为java.lang.Class,则表示不是泛型
System.out.println("ArrayList.class实现的第1个接口的泛型参数类型:"+((ParameterizedType)type2).getActualTypeArguments()[0]);

// 打印结果如下:
// ArrayList.class实现的第1个接口的类型:java.util.List<E>
// 返回值type2本身的实际类型:class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl

// ArrayList.class实现的第1个接口的泛型参数类型:E
这个一样只能获取到直接实现的 N 个接口(第一级接口),如果需要获取所实现接口的所实现接口的类型,就需要将获取到的类型转为 Class 对象,再重复执行方法。如果是接口类型是泛型的,则不能用 getTypeName(),而是需要用 getRawType()。

try {
     Class clazz = Class.forName(((ParameterizedType) type2).getRawType().getTypeName());
     Type type3 = clazz.getGenericInterfaces()[0];
     System.out.println("type3="+type3.getTypeName());
} catch (ClassNotFoundException e) {
     throw new RuntimeException(e);
}

// 打印结果如下:
// type3=java.util.SequencedCollection<E>
> 使用案例
?和 T 使用区别
特性
?
 通配符
T
 类型参数
含义    
未知类型
特定但未确定的类型
实例化    
不能创建实例
可以创建实例
类型安全    
只能当作 Object 使用
可以当作具体类型使用
添加元素    
通常不能添加
可以添加(类型安全)
读取元素    
只能当作 Object 读取
可以当作具体类型读取
使用场景    
只读操作、类型检查
需要创建实例、类型安全操作
选择使用 ? 还是 T 取决于你的具体需求:

如果只需要读取或检查类型信息,使用 ?
如果需要创建实例或进行类型安全的操作,使用 T

// 1. 代表未知类型
public void processClass(Class<?> clazz) {
    // clazz 可以是 Class<String>、Class<Integer> 等任意类型
    System.out.println(clazz.getName());  // 可以调用 Object 方法
    // clazz.newInstance();  // 编译错误:无法创建实例
}

// 2. 只读操作安全
public void printList(List<?> list) {
    for (Object item : list) {  // 只能当作 Object 处理
        System.out.println(item);
    }
    // list.add("abc");  // 编译错误:无法添加元素
}
// 1. 代表特定但未确定的类型
public <T> void processClass(Class<T> clazz) {
    // T 是确定的类型,只是在编译时还不知道具体是什么
    try {
        T instance = clazz.newInstance();  // 可以创建实例
        System.out.println(instance.getClass().getName());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

// 2. 类型安全的操作
public <T> void copyList(List<T> source, List<T> target) {
    for (T item : source) {
        target.add(item);  // 类型安全
    }
}

统一 API 结果封装

// 定义泛型结果类
@Data
public class Result<T> {

    private int code;

    private String msg;

    // 泛型字段,承载业务数据
    private T data; 

    // 成功静态工厂方法
    public static <T> Result<T> success(T data) {
        return new Result<>(200, "success", data);
    }
}
通用分页查询结果
@Data
public class PageResult<T> {

    private long total;

    private int pageNum;

    private int pageSize;

    // 泛型列表,存储分页数据
    private List<T> list;
}

// 使用示例
public PageResult<Order> getOrdersByPage(int pageNum, int pageSize) {
    List<Order> orderList = orderService.getOrders(pageNum, pageSize);
    long total = orderService.countOrders();
    return new PageResult<>(total, orderList, pageNum, pageSize);
}
extends 和 super 使用
通配符 ? 用于解决类型间的兼容性问题。<? extends T> 表示类型上限,只能获取元素;<? super T> 表示类型下限,只能插入元素。
class Animal {

}

class Dog extends Animal {

}

public class Main {
    public static void main(String[] args) {
        List<Dog> dogs = new ArrayList<>();
        // 读取数据,使用? extends
        readElements(dogs); 
        // 写入数据,使用? super
        writeElement(dogs); 
    }

    // 只能读取,不能写入
    public static void readElements(List<? extends Animal> list) {
        for (Animal animal : list) {
            System.out.println(animal);
        }
    }

    // 只能写入,不能读取
    public static void writeElement(List<? super Dog> list) {
        list.add(new Dog());
    }
}

策略模式结合泛型

public interface Handler<T> {
    // 判断是否支持处理该类型
    boolean supports(Class<?> clazz);

    // 处理数据
    void handle(T data); 
}
@Component
public class EcouponHandler implements Handler<Ecoupon> {

    @Override
    public boolean supports(Class<?> clazz) {
        return Ecoupon.class.isAssignableFrom(clazz);
    }

    @Override
    public void handle(Ecoupon ecoupon) {
        // 处理电子券的专属逻辑
    }
}
@Service
public class HandlerManager {

    @Resource
    private List<Handler<?>> handlers;

    public <T> void process(T data) {
        for (Handler<?> handler : handlers) {
            if (handler.supports(data.getClass())) {
                ((Handler<T>) handler).handle(data); // 类型安全转换后处理
                return;
            }
        }
        throw new UnsupportedOperationException("无支持处理器");
    }
}

获取类的超类或接口的 class 类型

public interface DealHandler<K, T> {

    T getTValue(K k);

    default Class<T> getTClass() {
        // 获取实现类中的T的class类型
        // 从父类中获取泛型参数
        Type superclass = this.getClass().getGenericSuperclass();
        if (superclass instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) superclass;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            if (actualTypeArguments.length > 1) {
                System.out.println("从父类成功获取到类型");
                return (Class<T>) actualTypeArguments[1];
            }
        }

        // 如果从父类获取不到,则尝试从接口获取
        Type[] genericInterfaces = this.getClass().getGenericInterfaces();
        for (Type genericInterface : genericInterfaces) {
            if (genericInterface instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) genericInterface;
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                if (actualTypeArguments.length > 1) {
                    System.out.println("从接口成功获取到类型");
                    return (Class<T>) actualTypeArguments[1];
                }
            }
        }
        throw new UnsupportedOperationException("无法获取泛型类型T的Class");
    }
}
public class DealHandlerImpl implements DealHandler<Integer, Double> {

    @Override
    public Double getTValue(Integer integer) {
        return 0.0;
    }

    public static void main(String[] args) {
        DealHandler<Integer, Double> dealHandler = new DealHandlerImpl();
        Class<Double> tClass = dealHandler.getTClass();
        System.out.println(tClass);
    }
}
public abstract class DealHandlerTemplate<K, T> implements DealHandler<K, T> {
}
public class DealHandlerTemplateImpl extends DealHandlerTemplate<Integer, String> {

    @Override
    public String getTValue(Integer integer) {
        return "";
    }

    public static void main(String[] args) {
        DealHandlerTemplate<Integer, String> dealHandlerTemplate = new DealHandlerTemplateImpl();
        Class<String> tClass = dealHandlerTemplate.getTClass();
        System.out.println(tClass);
    }
}
文档更新时间: 2025-12-05 08:49   作者:admin