I am new to generics in java. I came across a method declaration below. Can someone explain in layman terms?
public interface SomeService{
<A, C> C submit(ServiceEnum service, A request, Class<C> responseType);
}
Thank you in advance.
The interface declares a generic method with two type variables: A and C. The type of request is A (which could be any object type), and the type variable of the Class parameter responseType is C. It returns a variable of type C. So, if a Class<Integer> is passed as responseType, then an Integer will be returned.
A. request should just be Object.<A, C> is just the syntax for declaring two generic type parameters. It just so happens that the Map interface also has two type parameters. You could have said <A, C, D> to declare three type parameters if you really wanted.This declaration first defines two generic types A and C. Then it requires that the second parameter is of type A and that the third parameter is of type Class<C>. The return type of this method will be of type C, that type will match the class of the last parameter.
One example of calling this method would be:
OrderRequest request = new OrderRequest(...)
Class<OrderConfirmation> responseType = OrderConfirmation.class
OrderConfirmation confirmation = someService.submit(service, request, responseType);
In layman terms, dealing with generics can be explained this way:
In usual Java programming (without Generics)
You can assign variables. int a = 10;
You can assign objects. SomeClass objOfSomeClass = new SomeClass();
But when you come to Generics, where you specify type of Objects (the actual class names)
like List<String>, can you substitute String with some variable?
The variable should not accept usual objects and variables, JUST classnames.
Something like List<T> and then T = String.
And please note in this case, we call T as type variable. (Because it holds class type and not the object itself).
Such assignment of Class names/type is not allowed by Java compiler.
So here is what you do.
You specify the type variable in <> format.
interface GeometricShape<T> {
void drawShape();
T addShape(T anotherShape);
}
Now assume you have classes like Rectangle, Circle, etc.
So if you give GeometricShape<Circle>
then T addShape(T anotherShape); becomes Circle addShape(Circle anotherShape);
In this case, you specified the type variable T in the interface, and this T is available everywhere inside interface - to all methods.
Suppose I don't want it in full interface, just in one or two methods.
So, you can specify type variables in just only one single method too - by appending <A, C> (two type variables here) before return type of the method.
Just like what you have asked.
<A, C> C submit(ServiceEnum service, A request, Class<C> responseType);
Depending upon what arguments you pass as request and responseType, your A and C type variables will automatically be assigned to the class types of your actual arguments.
And in this case, the return type is C (depends upon what you actually pass as responseType).