我有以下 3 个类:
public class MyClass1<T extends MyClass1> {
private List list = new ArrayList();
public T add(Object... o) {
Collections.addAll(this.list, o);
return (T) this;
}
public MyClass2 two() {
MyClass2 n = new MyClass2();
add(n);
return n;
}
}
public class MyClass2<T extends MyClass2> extends MyClass1<MyClass2> {
public MyClass3 three() {
MyClass3 n = new MyClass3();
add(n);
return n;
}
}
public class MyClass3<T extends MyClass3> extends MyClass2<MyClass3> {
}
我想调用链中的方法。像这样:
MyClass1 m1 = new MyClass1();
m1.add(1).add(2).two().add(3).three().add(4);
出于某种原因add(3)
返回 MyClass1
,我原以为它会返回 MyClass2
.如果我删除 <T extends MyClass2>
来自 MyClass2
, add(3)
返回 MyClass2
根据需要,然后 MyClass3
无法扩展 MyClass2
有一个类型。
我怎样才能让它工作,这样我就可以链接我所有的方法并仍然使用 add(Object...)
来 self 所有类的方法?
更新:
以上显然是一个例子。我真正想在这里创建的是一个用于构建 MySQL 查询的简单工具。我有很多 EJB3 实体已经定义了我的表名和列名,但需要进行一些 native 查询,因为有些事情是 EJB-QL 无法实现的。然而,我不想在我的代码中多次指定表名和列名,因此需要一个可以使用 EJB3 实体创建 native MySQL 查询的工具。当我使用我创建的代码时,它可能看起来像这样:
new Query().select().field(MyEntity_.id).field(MyEntity_.name).field(MyOtherEnt_.type);
或者:
new Query().join().left(MyOtherEnt_.myEntityId);
这里我可能有一个 Query 对象,它指定了一些通用的 MySQL 语法,然后对其进行了扩展。它可能是这样的:Query > Extended by Select > extended by SubQuery。整个事情都是根据我正在从事的特定项目定制的。
最佳答案
add(3)
返回 MyClass1
因为方法 add
是类 MyClass1
的成员。您必须在扩展类中覆盖 add
方法才能返回不同的数据类型。
MyClass2
的定义应该差不多是这样
class MyClass2<T extends MyClass2> extends MyClass1<MyClass2> {
@Override
public T add(Object... o) {
super.add(o);
return (T)this;
}
public MyClass3 three() {
MyClass3 n = new MyClass3();
add(n);
return n;
}
}
无论如何,我不知道你想达到什么目的,但恕我直言,你采取了错误的方法。此外,当您创建新的参数化对象时,您没有声明类型 T
,所以总而言之,对于编译器和 JRE,这里的所有内容都只是 Object
类型。
关于java - 如何通过多级extends来解析一个泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19541859/