我知道这不是一个好问题,我可能会被问到这个问题而被诅咒,但我找不到任何地方可以就此问题寻求帮助

下面是我的面试问题中出现的一个通用类(我已经失败了)。问题是要告诉这个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的有效返回类型!在实践中这有关系吗?不知道,但这很酷。 :)

这不是最好的例子,但是这个问题是开放式的(“这种东西可能用来做什么?”)。当然,还有其他定义树的方法。

08-19 12:21