What can this general class declaration mean?

I know this is not a good question, and I could curse him, but I can’t find a place to get help on this.

Below is the general class that appeared in my interview (which I already failed). The question was to say what this class declaration does, and in what circumstances can it be used for?

I have a very limited understanding of general programming, but I understand that "T" is Type and "extends" here means that Type should inherit "SimpleGenericClass", but I don't understand "?" at the end and in what circumstances this class can potentially be used to

public abstract class SimpleGenericClass<T extends SimpleGenericClass<?>> { } 
+8
java generics generic-programming
source share
5 answers

First, since the SimpleGenericClass class is abstract, it must be a subclass.

Secondly, this is a general class, which means that somewhere inside the class you will almost certainly use the general parameter T as the type of the field.

 public abstract class SimpleGenericClass<T...> { T x; } 

Now the interesting thing first is that T bounded. Since it is declared as T extends SimpleGenericClass<?> , It can only be SimpleGenericClass<?> Or some subclass of SimpleGenericClass<?> . You also asked about thr ? . This is called a wildcard, and there is a pretty good explanation for this in the Java Wildcards Tutorial . In your case, we would say that it is "SimpleGenericClass of unknown". This is necessary in Java because SimpleGenericClass<Object> NOT a superclass of SimpleGenericClass<String> , for example.

An interesting second thing is that since T is a SimpleGenericClass some type, your class more than likely defines recursive structures. It seems to me that trees (think about expression trees), where SimpleGenericClass is a (abstract) node type, designed to subclass with all kinds of specialized node types.

UPDATE This SO question for self-limited generics may be helpful to you.

UPDATE 2

I went ahead and put together a code that illustrates how this can be used. An application does nothing but compile, and it shows you how general restrictions can provide some possibly significant restrictions.

 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[]{};} } 

It's nice that NumberNode[] is a valid return type for PlusNode.getChildren ! Does it matter in practice? I don’t know, but it's pretty cool. :)

This is not a good example, but the question was quite open ("what can it be used for?"). Of course, there are other ways to define trees.

+4
source share

This really means that you allow the user of the SimpleGenericClass class to parameterize the class instances with type T. However, T cannot be any type, but must be a subtype of SampleGenericClass (or SampleGenericClass itself).

In the rest of the code for the SimpleGenericClass class, you can use the type T in method signatures.

Suppose for a second that SimpleGenericClass is not abstract. When using it, you can write:

 new SimpleGenericClass<SampleGenericClass<String>>(); 

those. you parameterize SimpleGenericClass with SampleGenericClass and SampleGenericClass with a string.

0
source share

By definition, it says that SimpleGenericClass can work with the type <T> , which is a subclass of SimpleGenericClass.

Therefore, I assume that some operations will be performed that will work on <T> .

Now, to understand why one could define a template like this (maybe I don’t really think so), there could be a scenario in which SimpleGenericClass is an abstract class ( just implemented as OP: P ) and expects that Will he be able to work on any specific classes?

Guys, what do you think?

0
source share

This is basically sais: in this class you have a placeholder of type T and a restriction on this placeholder, it must be of type SimpleGenericClass or something that extends it. After you obey this rule, you can instantiate your class and give the actual type T, which can later be used in the methods of this class, something like this:

 public class C <T extends Number>{ public void doSomething(T t) { } public static void main(String... args) { //works: C<Number> c = new C<Number>(); c.doSomething(new Number() { //Aonimous implementation of number }); //won't work //C<Object> c = new C<Object>(); C<Integer> c2 = new C<Integer>(); c2.doSomething(new Integer(1)); //won't work //c2.doSomething(new Number() { //Aonimous implementation of number //}); } } 

SimpleGenericClass<?> currently pretty redundant. If another common type is needed for this class, you can have more than one ( SimpleGenericClass<T extends SimpleGenericClass, T2 extends Whatever> )

0
source share

I think you have a question in this form ( T instead ? ):

 public abstract class SimpleGenericClass<T extends SimpleGenericClass<T>> 

Take a look at this code:

 abstract class Foo<SubClassOfFoo extends Foo<SubClassOfFoo>> { /** subclasses are forced to return themselves from this method */ public abstract SubClassOfFoo subclassAwareDeepCopy(); } class Bar extends Foo<Bar> { public Bar subclassAwareDeepCopy() { Bar b = new Bar(); // ... return b; } } Bar b = new Bar(); Foo<Bar> f = b; Bar b2 = b.subclassAwareDeepCopy(); Bar b3 = f.subclassAwareDeepCopy(); // no need to cast, return type is Bar 

Trick with Foo<SubClassOfFoo extends Foo<SubClassOfFoo>> :

  • Any subclass of Foo must provide an argument of type Foo .
  • This type argument must be a subclass of Foo .
  • Foo subclasses (e.g. Bar ) follow the idiom that the type of argument they provide for Foo is itself.

  • Foo has a method that returns SubClassOfFoo . combined with the above idiom, this allows Foo to formulate a contract that says: "Any subclass of me should implement subclassAwareDeepCopy() and they should declare that it will return this actual subclass."

To say it another way: this idiom allows a superclass (for example, an abstract Factory) to define methods whose argument types and return types are of the type of the subclass and not the type of the superclass.

The trick is performed, for example, in the Enum JDK class:

 public abstract class Enum<E extends Enum<E>> 

See here for more details.

0
source share

All Articles