另一个泛型类的Java泛型类

jud*_*ine 6 java generics dao interface

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

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

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

public interface IdObjectDAO<T extends IdObject<U>> {
    public T getObjectById(U id);
}
Run Code Online (Sandbox Code Playgroud)

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

public interface IdObjectDAO<T extends IdObject<U extends Object>> {...}
Run Code Online (Sandbox Code Playgroud)

我收到“标记“扩展”,预期的语法错误的编译器错误。在没有编译器错误的情况下定义接口的唯一方法是:

public interface IdObjectDAO<T extends IdObject<? extends Object>> {...}
Run Code Online (Sandbox Code Playgroud)

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

public interface IdObjectDAO<T extends IdObject<U>, U> {...}
Run Code Online (Sandbox Code Playgroud)

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

public class     Person    extends IdObject<Integer> {...}
public interface PersonDAO extends IdObjectDAO<Person, Integer> {...}
                                                     ^^^^^^^^^ <== avoid this
Run Code Online (Sandbox Code Playgroud)

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

提前致谢!

Vin*_*ele 1

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

public T getObjectById(U id);
Run Code Online (Sandbox Code Playgroud)

您的界面在 和 中都是通用TU。接口无法确定Ufrom IdObject<U>,因此如果您想要编译时类型安全,则必须显式指定它。

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

1)失去类型安全性:

public interface IdObjectDAO<T extends IdObject<?>> {
    public T getObjectById(Object id);
}
Run Code Online (Sandbox Code Playgroud)

equals如果正确实现U,仍然可以成功调用

id.equals(t.getId());
Run Code Online (Sandbox Code Playgroud)

t对于类型为 的对象T

2)将您的 id 包装在类型的对象中T

public interface IdObjectDAO<T extends IdObject<?>> {
    public T getObjectBySample(T sample);
}
Run Code Online (Sandbox Code Playgroud)

你可以这样称呼它:

Integer id = 5;
Person sample = new Person(id);
Person object = personDao.getObjectBySample(sample);
Run Code Online (Sandbox Code Playgroud)