Java Generic: Can a Generic extends another Generic class? - java

Here, here is my question, I have three abstracts class which all are generic, and i want something like this:
public abstract class AbstracOne< T extends AbstractTwo< K extends AbstractThree<K> >>>
This is not working and I get the following error (on the second extends):
Syntax error on token "extends", , expected.
However, if I use the following code, it is working:
public abstract class AbstracOne< T extends AbstractTwo< ? extends AbstractThree<?> >>>
So, what is the difference between using K and ?
Thank you very much

Type parameter vs Type argument
You can read this excellent FAQ by Angelica Langer for clearing this distinction.
Generic class has type parameters which are substituted by type argument when you use the generic class.
Type parameters can have constraints. Type arguments can be fully qualified types or previously defined type parameters.
So, you can use K if it is defined already. You can also add constraints while defining it.
public abstract class AbstractOne<K extends AbstractThree<K>, T extends AbstractTwo<K>>
Good luck.

Related

Why won't Java let you inherit from a generic type-variable?

public class MyClass<T> extends T {...}
The above declaration will fail to compile with the error:
error: unexpected type
class MyClass<T> extends T {}
^
required: class
found: type parameter T
where T is a type-variable:
T declared in class MyClass
I can't really think of a reason for this to happen, so I am wondering if someone can shed some light on why it is that Java won't let you inherit from a generic type-variable.
The most obvious reason I can think of isn't even about type-erasure; it is the fact that when you make A a subclass of B, the Java compiler needs to know what constructors B has. If a class does not have a no-arguments constructor, then its sub-classes must call one of its defined constructors. But when you declare
public class MyClass<T> extends T {...}
It is absolutely impossible for the compiler to know what the super constructors are, since T is not fixed at compile-time (that's the whole point of generics after all), which is a situation that cannot be allowed in Java.
Java has quite a lot of language restrictions unlike C++ for example. What you want is not possible for many reasons listed in the comments (T might be final or have abstract methods). However, you are allowed to extend from a supertype having the generic type parameter:
public class MyClass<T> extends AnotherClass<T>
You might find the following alternative interesting:
public class MyClass<T extends AnotherClass> extends AnotherClass
What you want to do does make not much sense.
Your question is not so weird as it may look like :) Consider how would you deal with following:
Suppose your real class for T has a single constructor with 3 parameters. How would you implement the constructor of inherited class, if you don't know how to call the super constructor?
Suppose your real class for T has public final methods and you have defined methods with the same signature in the inherited class. What method would your object have? You cannot resolve such conflict.
Simple deductions based on your question.
T is a type.
MyClass extends T - MyClass is enhanced version of T.
MyClass < T> extends T - MyClass is enhanced T, but only for Type T.
there is no reason to state ' I extend T but only for type T'.
If you extend T, MyClass is already a Type of T & definitely not some X,Y or Z.
Generics are needed if you want to ensure Type safety, if you extend it is already type safe.

Java Generics - Class<Interface>

I have created an interface called Identifier. And a class which implements Identifier interface is MasterEntity bean like below.
public class MasterEntity implements Identifier{
}
In DAO method, I wrote a method like below method signature.
public Identifier getEntity(Class<Identifier> classInstance){
}
Now from Service I want to call the method like below.
dao.getEntity(MasterEntity.class);
But am getting compilation error saying -
The method getEntity(Class<Identifiable>) in the type ServiceAccessObject
is not applicable for the arguments (Class<MasterEntity>)
I know if I use like below it will work.
public Identifier getEntity(Class classInstance){
But by specifying the Class of type Identifiable, how it can be done?.
Change DAO method signature to
public Identifier getEntity(Class<? extends Identifier> classInstance)
By declaring method as you described above you specify that the only applicable argument is Identifier.class itself. To be able to accept Identifier.class implementations, you should define generic type bounds.
List<? extends Shape> is an example of a bounded wildcard. The ? stands for an unknown type, just like the wildcards we saw earlier. However, in this case, we know that this unknown type is in fact a subtype of Shape. (Note: It could be Shape itself, or some subclass; it need not literally extend Shape.) We say that Shape is the upper bound of the wildcard.
Also you can take a look at this answer: https://stackoverflow.com/a/897973/1782379

Generics in Java with and abstract class

I was reading some code for learn something about manage data in Android.
When i read a litle of the code...
I find this declaration.
public abstract class DBObject<T extends DBObject<?>> implements Cloneable{}
I understadn that this is and Abstract class with T that is a Generic Object
but i don't understand why y have to put a wildcart after Extend the same class.
Here is all the code
https://github.com/tasks/tasks/blob/master/src/main/java/com/todoroo/andlib/sql/DBObject.java
It looks like this is used so that it can be parameterised with its subclasses. It would be used like so:
class Foo extends DBObject<Foo> { ... }
It appears this is done solely so that the as() method will return the correct type.
The reason for the wildcard is because without it you would have to somehow specify a recursive generic definition, DBObject<T extends DBObject<T extends DBObject<...>>> - which is impossible.
Edit: Although see comments below; the wildcard is not actually necessary.

Generics in java just checking to make sure this is correct

I'm struggling with these (similar) problems on the bounded quantification of generics in Java:
Write the header for a generic class named MyType. The class should have one type parameter. The type parameter’s upper bound should be the String class.
Write the header for a generic class named MyType. The class should have one type parameter. The type parameter’s lower bound should be the Integer class.
public class myType<T extends String>{}
and
public class myType<T extends Integer>{}
is this correct im really having a hard time grasping the concept of generics in java
You don't use extends to define both the upper bound and the lower bound.
According to Wikipedia's article on Generics in Java...
To specify the upper bound of a type wildcard, the extends keyword is used...
So to define the upper bound, use extends:
public class myType<T extends String>{}
Again, according to Wikipedia's article on Generics in Java...
To specify the lower bounding class of a type wildcard, the super keyword is used.
Addendum
I think whoever originally put this question together needs to sort a few things out.
Java does not have header files. Look up Header Files on Wikipedia, and it immediately states that Java does not use them:
Some newer languages (such as Java) dispense with header files...
You cannot use a lower bound when defining a class - I believe it can only be done with a wildcard, which is not used when defining a class. The code public class MyClass<T super Integer> {} will give a syntax error: > expected
So all together, the question reeks of nonsense.

What does this generics code below do ?

I am unable to understand what the generics code below does. I am new to generics so would appreciate all the help i can get!
Public abstract class AMetadata< C extends CMetadata, P extends PMetadata, R extends RMetadata> extends GEntityMetada<C>
{
// class does stuff here
}
Could anyone explain how the classes are related ?
This specifies that the AMetadata class will deal with three generically-defined types, each of which are guaranteed to extend a different type (CMetadata, PMetadata, and RMetadata, respectively).
Furthermore, the AMetadata class itself extends the GEntityMetada generic class, with its generic argument being the first generic argument type (C, which extends CMetadata) passed to AMetadata.
To say how the classes are related would require more knowledge of the code base than this snippet provides. For example, it is possible (though unlikely) that a single type could actually extend CMetadata, PMetadata, and RMetadata, and that type could therefore be used as an argument to all three classes. But there is nothing in this generic definition to indicate that there has to be any relationship between these three classes.
The only other information you can really get from this is that a type that extends CMetadata is a valid generic parameter for the GEntityMetada class. Whether GEntityMetada requires its argument to extend CMetadata is unclear.
The generic type params are subtype of a class, e.g. C is a subtype of CMetadata in your example.
The class AMetaData extends a class GentityMetad. So it has a generic parameter C. I can't tell if GentityMetad puts any restrictions on C.
For AMetadata, there is an additional requirement on C: it must extend CMetadata.
In addition, the class AMetaData has two more generic types, P and R, which must extend PMetadata and RMetadata respectively. These are unrelated to GEntityMetad.
It just states what is the template of AMetadata you are willing to create.
I'll use short names for clearness. So assume your code looks like this:
public abstract class AM <C extends CM, P extends PM, R extends RM> extends GM<C>
This means that you can create AM object but you have to say what type of elements it should have. Here is the example:
AM<CMChild, PM, RMChild> extends GM<CMChild>

Categories

Resources