You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现泛型接口的方法?附相关泛型接口与方法代码示例

问题分析与解决方案

首先得指出你定义的ParsableDTO<T>接口里有个小问题——方法级的泛型<T>和接口的泛型参数重名了,这会导致接口的泛型被方法的泛型覆盖,完全失去了泛型接口的意义。咱们先把接口修正过来,再看具体的实现方式。

1. 修正泛型接口

把方法上的<T>去掉,让方法返回的类型就是接口定义的泛型参数T,这样才能和后续的泛型约束匹配:

public interface ParsableDTO<T> {
    T parse(ResultSet rs) throws SQLException;
}

2. 实现具体的DTO类

接下来以一个实际的DTO为例,比如UserDTO,实现修正后的ParsableDTO<UserDTO>,在parse方法里从ResultSet中读取数据库字段值,组装成当前DTO实例:

public class UserDTO implements ParsableDTO<UserDTO> {
    private Long id;
    private String username;
    private String email;

    // 无参构造器、Getter/Setter方法省略

    @Override
    public UserDTO parse(ResultSet rs) throws SQLException {
        UserDTO user = new UserDTO();
        user.setId(rs.getLong("id"));
        user.setUsername(rs.getString("username"));
        user.setEmail(rs.getString("email"));
        return user;
    }
}

这里的核心是:实现类要明确指定接口的泛型参数为自身类型(也就是F-bounded泛型,和你getParsableDTOs方法里的T extends ParsableDTO<T>约束对应),这样parse方法就能返回当前DTO的实例,保证类型安全。

3. 完善getParsableDTOs方法的循环逻辑

在你的getParsableDTOs方法的while(rs.next())循环里,需要通过传入的dto_class创建DTO实例,然后调用其parse方法填充数据:

public <T extends ParsableDTO<T>> List<T> getParsableDTOs(String table, Class<T> dto_class) {
    List<T> rtn_lst = new ArrayList<T>();
    ResultSet rs = doQueryWithReturn(StringQueryComposer.createLikeSelectQuery(table, null, null, null, true));
    try {
        // 获取DTO的无参构造器(如果DTO用有参构造,需调整参数类型匹配)
        Constructor<T> constructor = dto_class.getConstructor();
        while(rs.next()) {
            T dto = constructor.newInstance();
            // 调用parse方法从ResultSet中读取数据并填充DTO
            T parsedDto = dto.parse(rs);
            rtn_lst.add(parsedDto);
        }
    } catch (SQLException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
        // 这里可以根据业务需求处理异常,比如打印日志或抛出自定义异常
        e.printStackTrace();
    } finally {
        // 务必记得关闭ResultSet等数据库资源,避免泄漏
        try {
            if(rs != null) rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    return rtn_lst;
}

注意:Java 9之后Class.newInstance()已被标记为过时,推荐用Constructor.newInstance()来创建实例,这样能更清晰地处理构造器相关的异常。如果你的DTO没有无参构造器,需要调整构造器的获取逻辑,传入对应的参数类型即可。

额外说明

为什么要修正接口的泛型?原来的方法里的<T>是方法自身的泛型参数,和接口的<T>完全是两个独立的类型,编译器无法保证你返回的T就是实现接口的DTO类型,会导致getParsableDTOs方法的泛型约束失效,甚至运行时出现类型转换异常。修正后,接口的泛型和方法返回类型绑定,就能全程保证类型安全。

内容的提问来源于stack exchange,提问作者user4789408

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:40:11