tags:

views:

71

answers:

4

I'm trying to implement Spring's RowMapper interface, however, my IDE is prompting me to cast the return object to "T" and I don't understand why. Can anyone explain what I'm missing?

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?
    }
}
A: 

Because T != User.

Marvin Cohrs
+2  A: 

Try

public class UserMapper implements RowMapper<User> {
duffymo
Why isn't it UserMapper<User>?
MarkPenn
Because the generic only applies to RowMapper.
duffymo
Because RowMapper wants to know the type, but UserMapper is only for that type. So UserMapper is telling RowMapper, "this is my type". But nobody else is allowed to tell UserMapper what its type is - it already knows it.
Carl Manaster
Here is how I often think of generics and translate something like `UserMapper implements RowMapper<User>` in my head: "UserMapper is a RowMapper *of* User"
matt b
+6  A: 

If a row maps to a User, then it should be a RowMapper<User>

ie:


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;
    }
}
Michael D
A: 

The compiler does not know anything about T. Therefore, it is asking you to cast User to T. If you are only planning on using T as a type of User you can use the following to restrict the generic type and give the compiler more information.

public class UserMapper<T extends User> implements RowMapper<T>
...

If your code actually looks like that, you are always returning User and it is not dependent on T. Therefore you should just make the return type User and not T.

unholysampler