使用泛型类型实现接口

4

我正在尝试实现Spring的RowMapper接口,但是我的IDE提示我将返回对象强制转换为"T",我不明白为什么。有人可以解释一下我错过了什么吗?

public class UserMapper<T> implements RowMapper<T> {
    public T mapRow(ResultSet rs, int row) throws SQLException {
        User user = new User();
        user.firstName(rs.getInt("fname"));
        user.lastName(rs.getFloat("lname"));
        return user; // Why am I being prompted to cast this to "T", should this be fine?
    }
}

4
编译器如何知道 T 是代表 User?也许你的意思是应该实现接口,改为使用 implements RowMapper<User> 吗? - Kirk Woll
我认为编译器会从类的实例化中知道,即:new UserMapper<User>(); - MarkPenn
1
但是,当你说这个类是“UserMapper<T>”时,你正在表明可以为它的新实例指定任何类型。例如,“new UserMapper<String>()”。然而,该类只会返回一个“User”! - ColinD
4个回答

12
如果一行对应一个用户,则应该是一个RowMapper<User>实例。
即:

public class UserMapper implements RowMapper<User> {
    public User mapRow(ResultSet rs, int row) throws SQLException {
        User user = new User();
        user.firstName(rs.getInt("fname"));
        user.lastName(rs.getFloat("lname"));
        return user;
    }
}

3

尝试

public class UserMapper implements RowMapper<User> {

为什么不是UserMapper<User>? - MarkPenn
因为通用类型只适用于RowMapper。 - duffymo
因为 RowMapper 需要知道类型,但 UserMapper 只是针对该类型。所以 UserMapper 告诉 RowMapper,“这是我的类型”。但是没有人可以告诉 UserMapper 它的类型 - 它已经知道了。 - Carl Manaster
2
这是我经常思考泛型并在脑海中翻译类似 UserMapper implements RowMapper<User> 的方式:“UserMapper 是一个 User 的 RowMapper”。 - matt b

3
编译器并不了解 T。因此它要求你将 User 强制转换为 T。如果你计划将 T 仅用作 User 的类型,可以使用以下方法限制泛型类型并提供更多信息给编译器。
public class UserMapper<T extends User> implements RowMapper<T>
...

如果你的代码实际上看起来像这样,你总是返回User,而不是依赖于T。因此,你应该将返回类型直接定义为User,而不是T

0

因为 T != 用户。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接