假设我正在尝试编写一个函数来返回当前类型的实例.有没有办法T
引用确切的子类型(所以T
应该B
在课堂上引用B
)?
class A {
<T extends A> foo();
}
class B extends A {
@Override
T foo();
}
Run Code Online (Sandbox Code Playgroud) 这是Java中一个众所周知的习语.例如,参见SO讨论.所以基本上定义一个接口,实现它的类需要有一个方法来与你的类的对象进行比较:
public interface IComparable<T extends IComparable<T>> {
public int compare(T item);
}
Run Code Online (Sandbox Code Playgroud)
(注意:这显然是解决特定用例的一种不必要的复杂方法 - 请参阅此帖 -但我正在询问如何解释递归语法,更不用说特定的应用程序).
简而言之,这是一个递归定义,在递归中没有明显的结束,我没有看到编译器/类型系统如何解决这个问题.
此外,尝试输入单词("IComparable是一个类,其实例可以与实现IComparable接口的类的对象进行比较")产生一个不合逻辑的循环定义,这在哲学/逻辑/数学中是不可能的,但显然是在编译器设计中可行(!).
此外,似乎如果原始的习语语法是可接受的,那么也可以允许一个人说:
public interface IComparable<T extends IComparable<T extends IComparable<T>>> {
public int compare(T item);
}
Run Code Online (Sandbox Code Playgroud)
...但编译器显然只允许一个级别extend
.
任何人都可以帮助我理解这种递归的通用定义吗?
根据接受的答案(BartoszKP),我认为我现在理解的是:
不应将"递归"定义读作(表示"定义取决于"关系的箭头):
[ IComparable<T> ] -------> [ IComparable<T> ]
Run Code Online (Sandbox Code Playgroud)
......这是不合逻辑的(循环的),而是:
[ IComparable<T> ] ----------> [ list of methods (parameterized by T) ]
\ ^
\ |
\-------> [ type bound on T ]-------/
Run Code Online (Sandbox Code Playgroud)
...这不是不合逻辑的,因此在编译器中可行.因此,在文字中,定义IComparable
是根据它定义的方法列表和它在类型上定义的界限给出的,T
后者又取决于方法列表.所以,没有递归.
我想使用这样的界面:
public interface ResultItem {
public int getConfidence();
public boolean equals(ResultItem item);
public ResultItem cloneWithConfidence(int newConfidence);
}
Run Code Online (Sandbox Code Playgroud)
我通过表示语音识别结果的不同类型的对象来实现它.
我的想法是,我希望只比较同类的结果.也就是说,如果我创建一个类IntResult
实现ResultItem
,我希望方法签名变为:
public boolean equals(IntResult item);
public IntResult cloneWithConfidence(int newConfidence);
Run Code Online (Sandbox Code Playgroud)
我觉得我的界面中存在设计缺陷,因为现在我在cloneWithConfidence和返回ResultItem的其他方法的结果上使用非常难看的强制转换.
有没有更好的办法?
java中是否有一种编写通用接口的方法,以更方便的方式指出这种接口的实现者?
例如我写的界面:
public interface Updatable<T> {
void updateData(T t);
}
Run Code Online (Sandbox Code Playgroud)
我想指出只有实现者的实例可以在updateData(T t)方法中传递.
所以,我必须写这样的东西:
public class Office implements Updatable<Office> {
@Override
public void updateData(Office office) {
//To change body of implemented methods use File | Settings | File Templates.
}
...
...
...
}
Run Code Online (Sandbox Code Playgroud)
但似乎有点难看.你有更好的变种吗?
我正在创建JOOQ TableRecord的接口
<R extends TableRecord<R>>
Run Code Online (Sandbox Code Playgroud)
有人能够解释上面的这一行吗?
谢谢