Reputation: 2655
I found this code from a tutorial and I am guessing this method getUriBase
return type is String
, but not clear what part <T extends IEntity>
is playing in this method and why it is placed in the beginning?
public interface IUriMapper {
<T extends IEntity> String getUriBase(final Class<T> clazz);
}
Upvotes: 6
Views: 5164
Reputation: 14678
This is the convention of creating a generic method.
The syntax for a generic method includes a type parameter, inside angle brackets, and appears before the method's return type. For static generic methods, the type parameter section must appear before the method's return type.
If you see then before your return type String
you defining your type parameter T
. Now, coming to <T extends IEntity>
, by this basically you are creating a bounded type parameter, where-in you are telling the compiler that T
should only be a subclass of IEntity
.
An important thing to note is that you need to define <T extends IEntity>
before your method (this is what you call "generic method", more info coming...) because your interface is not a generic type, suppose your interface was like below then you need not to define the T
type parameter because compiler would know what is the T
type parameter.
public interface IUriMapper<T extends IEntity> {
String getUriBase(final Class<T> clazz);
}
So, basically generic method are useful (or in other words meant for situations) when you want to define your own type. Consider below example where-in your generic type (your interface "IUriMapper") defines type parameter "T" but for method getUriBase
you are creating a new type "E"
public interface IUriMapper<T extends IEntity> {
<E extends Number> String getUriBase(final Class<E> clazz);
}
This Oracle documentation is best source to learn Generics.
Upvotes: 4
Reputation: 2465
The type parameter section, delimited by angle brackets (<>), follows the class name. It specifies the type parameters (also called type variables) T1, T2, ..., and Tn.
public class Box {
private Object object;
public void set(Object object) { this.object = object; }
public Object get() { return object; }
}
To update the Box class to use generics, you create a generic type declaration by changing the code "public class Box" to "public class Box". This introduces the type variable, T, that can be used anywhere inside the class.
/**
* Generic version of the Box class.
* @param <T> the type of the value being boxed
*/
public class Box<T> {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
Source: https://docs.oracle.com/javase/tutorial/java/generics/types.html
There may be times when you want to restrict the types that can be used as type arguments in a parameterized type. For example, a method that operates on numbers might only want to accept instances of Number or its subclasses. This is what bounded type parameters are for.
public class Box<T> {
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
public <U extends Number> void inspect(U u){
System.out.println("T: " + t.getClass().getName());
System.out.println("U: " + u.getClass().getName());
}
public static void main(String[] args) {
Box<Integer> integerBox = new Box<Integer>();
integerBox.set(new Integer(10));
integerBox.inspect("some text"); // error: this is still String!
}
}
Source: https://docs.oracle.com/javase/tutorial/java/generics/bounded.html
Upvotes: 2