另一个泛型类的 Java 泛型类

Posted

技术标签:

【中文标题】另一个泛型类的 Java 泛型类【英文标题】:Java generic class of another generic class 【发布时间】:2014-08-02 15:23:05 【问题描述】:

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

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> ...

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

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

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

提前致谢!

【问题讨论】:

我认为两个参数版本是正确且唯一的方法。您希望编译器能够“查看”您的 IdObject 的 id 类型,但这是不可能的。 试试这个公共接口 IdObjectDAO public T getObjectById(U id); 这也应该回答你的问题:***.com/questions/14953029/… 【参考方案1】:

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

public T getObjectById(U id);

您的界面在TU 中都是通用的。接口无法从IdObject&lt;U&gt; 中确定U,因此如果您想要编译时类型安全,则必须明确指定它。

如果你真的坚持只提供T 作为通用参数,我能想到的两个(相当糟糕的)解决方法是:

1) 丢失类型安全性:

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

如果你正确地实现了Uequals,你仍然可以成功调用

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);

【讨论】:

以上是关于另一个泛型类的 Java 泛型类的主要内容,如果未能解决你的问题,请参考以下文章

Java泛型:泛型类泛型接口和泛型方法

另一个泛型类的 Java 泛型类

Java泛型:泛型类泛型接口和泛型方法

Java泛型知识点:泛型类泛型接口和泛型方法

反射获取泛型类泛型方法

Java泛型