我想了解以下是什么意思?
public class Bar<T extends Bar<T>> extends Foo<T> {
//Some code
}
做这样的事情有什么好处(例如用例?)。
答案 0 :(得分:7)
这是一个相当理论的例子,但在这种情况下你可能需要它:
public class Bar<T extends Bar<T>> extends Foo<T> {
private final T value;
public T getValue() { return value; }
public void method(T param) {
if (param.getValue().equals(someValue)) {
doSomething();
} else {
doSomethingElse();
}
}
}
如果T不是param.getValue()
,则无法致电Bar
,因为T extends Bar<T>
。
答案 1 :(得分:4)
这与定义java.lang.Enum
类的方式非常相似:
public abstract class Enum<E extends Enum<E>> implements Comparable<E> {
private final String name;
private final int ordinal;
protected Enum(String name, int ordinal) {
this.name = name; this.ordinal = ordinal;
}
public final String name() { return name; }
public final int ordinal() { return ordinal; }
public String toString() { return name; }
public final int compareTo(E o) {
return ordinal - o.ordinal;
}
}
由于这样定义的类必须是抽象并且无法直接实例化,因此该模式在与扩展普通枚举的方式类似的构造中很有用:
// corresponds to
// enum Season { WINTER, SPRING, SUMMER, FALL }
final class Season extends Enum<Season> {
private Season(String name, int ordinal) { super(name,ordinal); }
public static final Season WINTER = new Season("WINTER",0);
public static final Season SPRING = new Season("SPRING",1);
public static final Season SUMMER = new Season("SUMMER",2);
public static final Season FALL = new Season("FALL",3);
private static final Season[] VALUES = { WINTER, SPRING, SUMMER, FALL };
public static Season[] values() { return VALUES.clone(); }
public static Season valueOf(String name) {
for (Season e : VALUES) if (e.name().equals(name)) return e;
throw new IllegalArgumentException();
}
}
“Java Generics and Collection”一书中的示例。
答案 2 :(得分:3)
您基本上将Bar
将“处理”的类型限制为扩展Bar<T>
的任何内容。在这种情况下,您希望确保Bar
仅处理自身的扩展 - 可能会调用Bar
专用的方法。一个简单的例子是,您可以使用此类来实现一种链接列表,并在执行仅Bar
可以/应该执行的操作时对其进行迭代。假设你有以下代码:
public class Bar<T extends Bar<T>> extends Foo<T> {
private T next;
//Initialize next in constructor or somewhere else
private void doSomethingOnlyBarCanDo(){
//Do it...
}
public void iterate(){
T t = next;
while(t != null){
t.doSomethingOnlyBarCanDo();
t = t.next;
}
}
}
使用这种构造,迭代Bar
实例的“链”非常容易,因为每个实例都会引用下一个实例 - 回忆T
扩展Bar<T>
,所以你可以这样引用它。
答案 3 :(得分:2)
一个典型的用例是Wrapper / Decorator模式。 Bar
可能包含T
本身的Bar
。 Foo
只是一个处理T
的参数化类。
public abstract class Foo<T> {
public abstract void foo(T t);
}
public class Bar<T extends Bar<T>> extends Foo<T> {
private T wrapped;
public Bar(T w) {
this.wrapped = w;
}
public abstract void foo(T t) {
// do something
}
}
答案 4 :(得分:0)
我唯一可以告诉<T extends Bar<T>>
使用此信息,您告诉T
现在属于Bar<T>
类型,这意味着T
是Bar
所以您可以访问Bar
可用的所有方法,否则如果您Bar<T>
T
您将无法访问它,因为public class CustomList<T extends List<T>> {
T t;
T get(int index) {
//Some custom code here
return t.get(index);
}
}
将是通用的。
什么是使用呢?
您可以将此用于构图。 e.g。
{{1}}
你的例子有点不对,因为Telling没有真正的优势T是Type Bar,因为你总是可以访问Bar类中的Bar类方法