Java泛型类的另一个泛型类

时间:2014-06-12 10:24:18

标签: java generics interface dao

我有一个基类泛型类,表示我的模型中具有任何类型标识符的所有对象:

public abstract class IdObject<T> {
    private T    id;
    public  T    getId()     { return this.id; }
    public  void setId(T id) { this.id = id;   }
}

然后,我有一个超级接口代表那些IdObject对象的DAO:

public interface IdObjectDAO<T extends IdObject<U>> {
    public T getObjectById(U id);
}

但是我得到编译错误“U无法解析为某种类型”。如果我通过以下方式更改接口定义:

public interface IdObjectDAO<T extends IdObject<U extends Object>> {...}

我得到编译器错误“令牌上的语法错误”扩展“,预期”。定义没有编译器错误的接口的唯一方法是:

public interface IdObjectDAO<T extends IdObject<? extends Object>> {...}

但是我没有public T getObjectId(U id)方法的类型别名(U)。我发现解决它的唯一解决方案是使用2种类型的参数:

public interface IdObjectDAO<T extends IdObject<U>, U> {...}

但我想避免使用这两个类型参数来避免在模型和DAO类中指定标识符类型:

public class     Person    extends IdObject<Integer> {...}
public interface PersonDAO extends IdObjectDAO<Person, Integer> {...}
                                                     ^^^^^^^^^ <== avoid this

任何人都可以用另一种方式来实现这种泛型的通用或定义IdObjectDAO接口吗?

提前致谢!

1 个答案:

答案 0 :(得分:1)

接口不仅仅由其名称定义,它还包含其中定义的所有方法的签名。既然你有方法

public T getObjectById(U id);

您的界面在TU中都是通用的。接口无法从U确定IdObject<U>,因此如果您希望编译时类型安全,则必须明确指定它。

如果你真的坚持只提供T作为通用参数,我可以提出的两个(非常糟糕的)解决方法是:

1)失去类型安全:

public interface IdObjectDAO<T extends IdObject<?>> {
    public T getObjectById(Object id);
}

如果您正确实施equals U,您仍然可以成功拨打

id.equals(t.getId());

表示t类型的对象T

2)将您的ID包裹在T类型的对象中:

public interface IdObjectDAO<T extends IdObject<?>> {
    public T getObjectBySample(T sample);
}

你可以这样称呼:

Integer id = 5;
Person sample = new Person(id);
Person object = personDao.getObjectBySample(sample);