另一个泛型类的Java泛型类

6
我有一个基础通用类,代表了我的模型中所有具有任何类型标识符的对象:
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>> {...}

我遇到了编译器错误"Syntax error on token 'extends', , expected"。唯一定义接口而不出现编译器错误的方法是:
public interface IdObjectDAO<T extends IdObject<? extends Object>> {...}

但是我没有类型别名(U)用于public T getObjectId(U id)方法。我找到的唯一解决方法是使用两个类型参数:

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
我认为双参数版本是正确且唯一的方法。你期望编译器能够“查看”你的IdObject中的id类型,但这是不可能的。 - Chris
尝试一下:public interface IdObjectDAO<T,U> { public T getObjectById(U id); } - Lluis Martinez
这也应该回答了你的问题:https://dev59.com/7W7Xa4cB1Zd3GeqPsKIg - Einar Bjerve
1个回答

1

接口不仅由其名称定义,还包括其中定义的所有方法的签名。由于您有该方法

public T getObjectById(U id);

你的接口在 TU 中都是通用的。接口无法从 IdObject<U> 中确定 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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接