在Morphia中使用泛型

时间:2012-09-09 19:38:03

标签: java generics morphia

虽然我将此问题标记为Morphia问题,但我认为这更为一般,但无论如何,我们都会感谢您的帮助。

我有 IUser 界面,我无法控制它:

public interface IUser<T> {
    ...
    public String getFirstName();
    ...
}

我也有这个界面的实施用户(Morphia实体):

@Entity
public class User implements IUser<ObjectId> {
    @Id
    private ObjectId id;

    @Property
    private String firstName;

    public String getFirstName() {
        return this.firstName;
    }
    ...
}

当Morphia要求映射类时,我提供User.class,因为这是Morphia实体。因此,当我扩展BasicDAO时,我提供用户 ObjectId 作为类型:

public class UserDAO extends MongoDAO<User, ObjectId> {
    public List<IUser<ObjectId>> getUsers(String id) {
        return ds.find(IUser.class, Mapper.ID_KEY, new ObjectId(id)).asList(); 
    }
}

现在,问题出现在 getUsers 方法中。如您所见,我想继续使用此类之外的接口;这就是我期望List<IUser<ObjectId>>作为返回类型的原因。

ds.find(...)方法的第一个参数是Class<T>类型,因此我提供了IUser.class。但是,正因为如此,我不能再期望List<IUser<ObjectId>>,而只是List<IUser>。{{1}}。这样,我就失去了IUser的类型。是否有可能迫使这个Morphia的方法返回一个参数化的IUser对象列表?

提前谢谢你, 兹拉特科

1 个答案:

答案 0 :(得分:0)

有几种选择。

Guava,Guice和类似的库所做的是接受一个TypeToken,它利用一个匿名内部类来重新定义类型。它看起来像这样:

return ds.find(new TypeToken<IUser<ObjectId>>(){}, ...);

但很明显,这不是一个真正的选择,因为你无法改变库。然而,我认为这是正确的解决方案。

第二个选项是强制转换类以包含泛型参数。这导致未经检查的警告,但需要抑制或忽略:

@SuppressWarnings({"unchecked"}) 
Class<IUser<ObjectId>> userClass = (Class<IUser<ObjectId>>) (Object) IUser.class;
return ds.find(userClass, ...);

编辑:

应该注意的是,上面的建议实际上并不比在返回之前将整个列表从List<IUser>转换为List<IUser<ObjectID>>更好。两者都有相同的需要抑制警告。