What does this generics code below do ? - java

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>

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 Generic: Can a Generic extends another Generic class?

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.

Understanding java recursive generic type definitions with type erasion

I'm very confused facing this line of code:
public abstract class ClassName<T extends ClassName<?>>{}
I know what <T> is, what abstract is, what inheritance is but I just can't summarize all I see in this line.
Please can someone explain in simple words what does that interesting thing means?
Not a duplicate of questions about <T> and <?>. The confusing thing here is that ClasName appears twice.
Thanks in advance.
public means the class is visible to all other classes.
abstract means the class can not be instantiated (you'll have to find a non-abstract subclass for that)
inheritance is an important concept in object-oriented programming. Read a book about OOP or consult wikipedia.
T extends ClassName<?> means there is an upper bound put on the type parameter T, such that T needs to be a subclass of ClassName<?>. ? means unbounded type parameter.
I will provide a little more meaningful example that might make it easier to understand the concept of using bounded recursive type parameters. Lets assume you have a class Thingy. You want all subclasses of Thingy to be comparable, but just to the same subclass. Ie you want nails to be comparable to nails, but not bikes:
interface Thingy<T extends Thingy<T>> extends Comparable<T> {}
class Nail implements Thingy<Nail> {
#Override public int compareTo(Nail o) { ... }
}
class Bike implements Thingy<Bike> {
#Override public int compareTo(Bike o) { ... }
}
So ClassName has a generic parameter T and this parameter needs to fit a certain requirement, in this case extends a certain type S, that means, T must inherit S. Now the interesting thing in this case is this S.
We have S to be ClassName<?>, so T must inherit from ClassName with a wildcard. For the wildcard aka the question mark please have a look at the link Michael Markidis gave in a comment to your question.
The real fun now is that this definition
public abstract class ClassName<T extends ClassName<?>>
allows recursive generic type defintion. So you could have something like
ClassName<ClassName<ClassName<ClassName<?>>>> test;
for whatever that's worth :)
EDIT: Given
ClassName2<T extends ClassName<?>> extends ClassName<T>
thats relatively easy in comparison. We want to inherit ClassName but not "destroy" the generic argument, so we take one ClassName would accept, in this case T extends ClassName<?>. In extends ClassName<T> the compiler checks if this (i.e. ClassName2's) T fits the T of ClassName, which was the requirement (remember ClassName's definition) T extends ClassName<?>, so this obviously works.
In addition, we have ClassName2<?> extending ClassName<?>, so now you can mix the two types however you want:
ClassName2<ClassName<ClassName<ClassName<?>>>> test2;
ClassName2<ClassName<ClassName2<ClassName<?>>>> test3;
However, if you would have, say
class ClassName3<T extends ClassName3<?>> extends ClassName<T>
(the public and abstrac modifiers don't really influence the generic behavior here), you can only have things like
ClassName3<ClassName3<ClassName3<ClassName3<?>>>> test4;
ClassName2<ClassName<ClassName3<ClassName3<?>>>> test5;
since ClassName and ClassName2don't inherit ClassName3.

type parameters generics in interfaces and concrete classes

I'm creating something like this and got struck about the usage of generics in java.
Idea: Producer produces something of type T and consumers contains command objects, command objects holds different mediators. Mediators holds objects of type Subject and updates values of type T
Note: I'm doing this to understand how generics works in terms of inheritance of the generic types and composition of the type parameter definitions in generic type intefaces and concrete classes, so please don't bother about rationale of the design.
Interfaces definitions:
Composition:
IObserver
ISubject which holds object of type T and IObserver.
IMediator holds objects of type ISubject and type T
ICommand holds objects of type IMediator and type T
IProducerConsumer holds objects of type T and ICommand.
There are some concrete Objects for the corresponding interfaces.
I defined interfaces like this:
public interface IObserver<T>
public interface ISubject<T,O extends IObserver<T>>
Cool until now. But Now the problems started.
public interface IMediator<T,S extends ISubject<T,O>, O extends IObserver<T>>
compiler is forcing me to do this. I mean O extends IObserver<T> as above. So, I infered that I can't define like below
public interface IMediator<T,S extends ISubject<T,O extends IObserver<T>> >
I concluded: that inner type parameter definition must not be expanded as above.
So, finally happy with
public interface IMediator<T,S extends ISubject<T,O>, O extends IObserver<T>>
Now mess started in ICommand
public interface ICommand <T,M extends IMediator<T, ?, ?>>,
I'm struck now compiler is not accepting many of my possibilities even what inference i made as above. I mean
public interface ICommand <T,M extends IMediator<T, S, o>, S extends ISubject<T, IObserver<T>>,O extends IObserver<T>>
is not working.
I don't want to user wild card I want to tell to the compiler something more concrete.
My questions are:
Is my inference correct as in ICommand definition.
How to interpret the above case studies.
What are the best defintions assuming that I want to insert T and must able to get and put.
What is the rules and relations of the type parameter definitions in interface and implemented classes.
Please explain ?
Generics with Bound Parameters (no wildcards)
Is my inference correct as in ICommand definition?
No. Two reasons
You have written a small 'o' while passing it to Mediator. (I guess it's just a typing mistake.)
You passed IObserver<T> in stead of O to ISubject which would definitely cause a parameter bound mismatch.
Correct Version:
interface ICommand<T, M extends IMediator<T, S, O>, S extends ISubject<T, O>, O extends IObserver<T>>
How to interpret the above case studies?
The first thing you'd need to understand that you have one unknown type T and five interfaces.
Therefore you would have total six concrete types which have to be included progressively in the interface declarations. (You explicitly asked not to bother about rationale of the design.)
If you write them in a correct order, it becomes much more manageable.
Interface declarations:
interface IObserver<T>
interface ISubject<T, O extends IObserver<T>>
interface IMediator<T, O extends IObserver<T>, S extends ISubject<T,O>>
interface ICommand<T, O extends IObserver<T>, S extends ISubject<T, O>,
M extends IMediator<T, O, S>>
interface IProducerConsumer<T, O extends IObserver<T>, S extends ISubject<T, O>,
M extends IMediator<T, O, S>, C extends ICommand<T, O, S, M>>
What are the best defintions assuming that I want to insert T and must able to get and put?
If you want to get and put object of type T, what you probably need is bunch of interfaces which take only one parameter T. Generics will enforce that all would be compatible as T will be replaced by same type everywhere.
Your current system is too rigid. In real scenario, you would never have so many implementations of these interfaces (unless you are re-implementing facebook in java) so that you'd have many possible combinations of the implementations and you want to ensure compatibility.
Generics enforces type-safety by applying restrictions which are good. But you should not put restrictions just because you can put them. You are losing flexibility, readability and maintainability of your code.
You should add bounds only when you need them. They should not affect the design in any way before contracts between interfaces have been decided.
Possibly sufficient way:
interface IObserver<T>
interface ISubject<T>
interface IMediator<T>
interface ICommand<T>
interface IProducerConsumer<T>
What is the rules and relations of the type parameter definitions in interface and implemented classes?
The only relation between type parameters in interfaces and implementing class that I can think of is that implementing class has to provide a type to replace the generic type parameter.
In some cases, that type can again be a generic type in which case the responsibility of providing concrete type is forwarded to the code using the class reference or another class which extends that class. It may even be recursive!
The rules are not written in the language, in stead, you are applying all the rules on this mechanism when you make any type parameter bound. So as long as you are supplying a type which qualifies against all of your rules, you are good to go.
More rules means more robust but less flexible/readable. So do the trade of wisely.
Two simple cases:
// General way
private class ProductObserver implements IObserver<Product> { }
private ProductObserver productObserver;
// Aspect oriented way
private class LoggerObserver<T> implements IObserver<T> { }
private LoggerObserver<Product> loggerObserver;
Lastly, I'd suggest you to read (comprehensive) Java Generics FAQ by Angelika Langer if you have any further doubt.
If you keep experimenting like this, you might as well end up inventing a design pattern. Don't forget to share it with us when you do :D
Hope this helps.
Good luck.

Java abstract class extends two classes

I have got a similar line digging up a OpenSource Project:
abstract class AbstractClass<A extends ParentClass1,
B extends ParentClass2>
Can you please tell me what actually it means? I think java does not support multiple inheritance so what actually we are doing here? And what is A and B here? :S
Here A and B are just place holders which can be replaced with any class that extends ParentClass1 and ParentClass2 respectively. You can pass arguments in angular brakets(<>) when you create object of this class. These arguments will be substituted for A and B by the compiler during compilation.
The above code does not indicate multiple inheritance. Please read generics in detail to understand this.
it's generic type
look here for generics: http://docs.oracle.com/javase/tutorial/java/generics/types.html
If you remove the content within <>, then you see its only
abstract class AbstractClass
that means, the class is not extending any classes at all.
abstract class AbstractClass<A extends ParentClass1,
B extends ParentClass2>
essentially means, the class would like to declare 2 generics A and B, and force its type. That means, it want the implementer of the class to supply the 2 classes which extends ParentClass1 and ParentClass2 respectively.
Please see this for more clarification

Categories

Resources