我知道这不是一个好问题,我可能会被问到这个问题而被诅咒,但我找不到任何地方可以就此问题寻求帮助
下面是我的面试问题中出现的一个通用类(我已经失败了)。问题是要告诉这个Class声明在做什么,在什么情况下可以用于?
我对泛型编程的了解非常有限,但我知道“T”是Type,而“extends”在这里意味着Type应该继承了“SimpleGenericClass”,但我不理解“?”。最后,在什么情况下可以将该类用于
public abstract class SimpleGenericClass<T extends SimpleGenericClass<?>> {
}
最佳答案
首先,因为类SimpleGenericClass
是抽象的,所以它应该被子类化。
其次,它是一个通用类,这意味着您几乎可以肯定在某个地方的类内部使用通用参数T
作为字段的类型。
public abstract class SimpleGenericClass<T...> {
T x;
}
现在的第一个有趣的事情是
T
是有界的。因为它被声明为T extends SimpleGenericClass<?>
,所以只能是SimpleGenericClass<?>
或SimpleGenericClass<?>
的某些子类。您还询问了thr ?
。这就是通配符,在the Java Tutorial on Wildcards上有一个很好的解释。在您的情况下,我们会说这是“未知的SimpleGenericClass”。在Java中是必需的,因为SimpleGenericClass<Object>
并不是SimpleGenericClass<String>
的超类。第二个有趣的事情是,由于
T
是某种SimpleGenericClass
,因此您的类很有可能定义了递归结构。我想到的是树(认为是表达式树),其中SimpleGenericClass
是(抽象)节点类型,旨在用各种专用节点类型进行子类化。UPDATE This SO question on self-bounded generics可能对您有所帮助。
更新2
我继续整理一些代码,说明如何使用它。该应用程序不执行任何操作,但会进行编译,并向您显示通用范围如何提供一些可能有意义的约束。
public abstract class Node<T extends Node<?>> {
public abstract T[] getChildren();
}
class NumberNode extends Node {
int data;
public Node[] getChildren() {return new Node[]{};}
}
class IdentifierNode extends Node {
int data;
public Node[] getChildren() {return new Node[]{};}
}
class PlusNode extends Node {
NumberNode left;
NumberNode right;
public NumberNode[] getChildren() {return new NumberNode[]{};}
}
这里的好处是
NumberNode[]
是PlusNode.getChildren
的有效返回类型!在实践中这有关系吗?不知道,但这很酷。 :)这不是最好的例子,但是这个问题是开放式的(“这种东西可能用来做什么?”)。当然,还有其他定义树的方法。