我知道这不是一个好问题,我可能会被诅咒问这个问题,但我找不到任何地方可以获得这个问题的帮助,
下面是我的面试问题中出现的通用类(我已经失败了)。问题是要告诉这个类声明正在做什么以及在什么情况下可以使用它?
我对泛型编程的理解非常有限,但我知道“T”是类型,“扩展”在这里意味着类型应该继承“SimpleGenericClass”,但我不理解“?”最后以及在什么情况下可以使用该类
public abstract class SimpleGenericClass<T extends SimpleGenericClass<?>> {
}
I know this isn't a good question to ask and I might get cursed to ask it but I cannot find any place to get help on this question
Below is a Generic class that appeared in my interview question (which I have already failed). The question was to tell what this Class declaration is doing and in what circumstances this could be used for ?
I have very limited understanding of Generic programming but I understand that 'T' is Type and 'extends' here means that the Type should have inherited 'SimpleGenericClass' but I do not understand the '?' at the end and in what circumstances this Class could be potentially used for
public abstract class SimpleGenericClass<T extends SimpleGenericClass<?>> {
}
发布评论
评论(5)
首先,因为
SimpleGenericClass
类是抽象,所以它应该被子类化。其次,它是一个通用类,这意味着在类内部的某个地方,您几乎肯定会使用通用参数
T
作为字段的类型。现在,第一个有趣的事情是
T
是有界的。因为它被声明为T extends SimpleGenericClass
,所以它只能是SimpleGenericClass
或SimpleGenericClass>
的某个子类>。您还询问了?
。这就是所谓的通配符,在 Java 通配符教程。在你的情况下,我们会说这是一个“未知的 SimpleGenericClass”。在 Java 中需要它,因为SimpleGenericClass
第二有趣的事情是,由于
T
是某种SimpleGenericClass
,您的类很可能定义递归结构< /em>.我想到的是树(想想表达式树),其中 SimpleGenericClass 是(抽象)节点类型,旨在用各种专用节点类型进行子类化。更新 这个关于自界泛型的问题可能是对你有帮助。
更新2
我继续编写了一些代码来说明如何使用它。该应用程序不执行任何操作,但它会进行编译,并向您展示通用边界如何提供一些可能有意义的约束。
这里的好处是
NumberNode[]
是PlusNode.getChildren
的有效返回类型!这在实践中重要吗?不知道,但这很酷。 :)这不是最好的例子,但问题相当开放(“这样的东西可以用来做什么?”)。当然,还有其他方法来定义树。
First, because the class
SimpleGenericClass
is abstract, it is meant to be subclassed.Second, it is a generic class which means that inside the class somewhere you will almost assuredly be using the generic parameter
T
as the type of a field.Now the first interesting thing here is that
T
is bounded. Because it is declared asT extends SimpleGenericClass<?>
it can only beSimpleGenericClass<?>
or some subclass ofSimpleGenericClass<?>
. You also asked about thr?
. That's known as a wildcard and there is a pretty good explanation of it at the Java Tutorial on Wildcards. In your case we would say this is a "SimpleGenericClass of unknown." It is needed in Java becauseSimpleGenericClass<Object>
is NOT the superclass ofSimpleGenericClass<String>
, for example.The second interesting thing though is that since
T
is aSimpleGenericClass
of some sort, your class is more than likely defining recursive structures. What comes to my mind are trees (think of expression trees) whereSimpleGenericClass
is the (abstract) node type, designed to be subclassed with all kinds of specialized node types.UPDATE This SO question on self-bounded generics might be helpful to you.
UPDATE 2
I went ahead and put together some code that illustrates how this can be used. The app doesn't do anything but it does compile and it shows you how the generic bounds can supply some possibly-meaningful constraints.
The nice thing here is that
NumberNode[]
is a valid return type forPlusNode.getChildren
! Does that matter in practice? No idea, but it is pretty cool. :)It's not the greatest example, but the question was rather open ended ("what might such a thing be used for?"). There are other ways to define trees, of course.
这实际上仅意味着您允许 SimpleGenericClass 类的用户使用类型 T 来参数化该类的实例。但是,T 不能是任何类型,而必须是 SampleGenericClass(或 SampleGenericClass 本身)的子类型。
在类 SimpleGenericClass 的其余代码中,您可以在方法签名中使用类型 T。
让我们假设 SimpleGenericClass 不是抽象的。使用它时,您可以这样写:
即您用 SampleGenericClass 参数化 SimpleGenericClass,用 String 参数化 SampleGenericClass。
This really only means that you allow the user of class SimpleGenericClass to parametrize instances of the class with the type T. However, T cannot be any type, but must be a subtype of SampleGenericClass (or SampleGenericClass itself).
In the remainder of the code of class SimpleGenericClass you may use type T in method signatures.
Let's assume for a second that SimpleGenericClass is not abstract. When using it, you could then write:
I.e. you parametrize SimpleGenericClass with SampleGenericClass and SampleGenericClass with String.
这基本上是说:在这个类中,您有一个名为 T 的类型占位符,并且对该占位符的限制是,它必须是 SimpleGenericClass 类型或扩展它的类型。一旦遵守该规则,您就可以创建类的实例并向 T 提供实际类型,稍后可以在该类的方法中使用该类型,如下所示:
SimpleGenericClass
是在这一点上相当多余。如果此类需要另一种泛型类型,则可以有多个泛型类型 (SimpleGenericClass
)This basically sais: in this class you have a Type placeholder called T, and a restriction on that placeholder, it must be of type SimpleGenericClass or something that extends it. Once you obey that rule you can create instances of your class and give an actual type to T, that later on can be used in methods of that class, something like this:
The
SimpleGenericClass<?>
is pretty redundant at this point. If another generic type is needed on this class, you can have more than one (SimpleGenericClass<T extends SimpleGenericClass, T2 extends Whatever>
)根据定义,它表示
SimpleGenericClass
可以在
类型上工作,该类型是 SimpleGenericClass 的子类。所以我假设会有一些操作适用于
。现在看看为什么人们会定义这样的模板 - (我真的想不到太多)可能是这样一种情况,其中
SimpleGenericClass
是一个抽象类(刚刚意识到它是按照OP:P)并期望它可以在任何具体类上工作?伙计们你觉得怎么样?
By definition it says that the
SimpleGenericClass
can work on a type<T>
which is subclass of SimpleGenericClass.So I assume there will be some operations which will work on
<T>
.Now to see why one would define a template like this - (not much I can think of , really ) may be a scenario where the
SimpleGenericClass
is an abstract class (just realized it is as per OP :P) and expects that it can work on any concrete classes ?Guys what do you think ?
我想您已经得到了这种形式的问题(
T
而不是?
):看一下这段代码:
Foo>
是:Foo
的任何子类都必须向Foo
提供类型参数。Foo
的子类(如Bar
)遵循以下习惯用法:类型它们提供给
Foo
的参数是它们自己。Foo 有一个返回
SubClassOfFoo
的方法。组合通过上面的习惯用法,这使得 Foo 可以制定一个合约:
说“我的任何子类都必须实现
subclassAwareDeepCopy()
并且他们必须声明它返回实际的子类“。
换句话说:这个习惯用法允许超类(例如抽象工厂)定义其参数类型和返回类型是子类类型而不是超类类型的方法。
例如,该技巧在
Enum
JDK 类中完成:请参阅此处了解更多详情。
I guess you have got the question in this form (
T
instead of?
):Take a look at this code:
The trick going on with
Foo<SubClassOfFoo extends Foo<SubClassOfFoo>>
is:Foo
must supply a type argument toFoo
.Foo
.Subclasses of
Foo
(likeBar
) follow the idiom that the typeargument they supply to
Foo
is themselves.Foo has a method that returns
SubClassOfFoo
. Combinedwith the above idiom, this allows Foo to formulate a contract that
says “any subclass of me must implement
subclassAwareDeepCopy()
andthey must declare that it returns that actual subclass“.
To say that another way: this idiom allows a superclass (such as an Abstract Factory) to define methods whose argument types and return types are in terms of the subclass type, not the superclass type.
The trick is done for example in
Enum
JDK class:Refer here for more details.