Reputation: 18551
I have a class called TResult
public class TResult<T extends MyEntity> {
public List<T> getEntityList() {
return entityList;
}
}
And I have a static method in other some class that returns it
public static TResult getAllEntities(final Class clazz, RouteFilter filter ){
}
Now, when I call getAllEntities I need to cast it to MyEntity otherwise i get a warning (unchecked assignment). I try to change the method signature and it only works with
public static <T extends APIBaseEntity> TResult<T> getAllEntities(final Class clazz, RouteFilter filter) {}
Why do I have to point that T extends APIBaseEntity in getAllEntities method when it is already defined in TResult class signature?
TResult<APIBaseEntity> allEntities = GeneralCRUD.getAllEntities(APIAccount.class, filter);
Upvotes: 3
Views: 2716
Reputation: 37859
First of all, you should not use raw types*, it would help you understand what you're doing with generic classes.
Ask yourself these questions: What class is clazz
? What kind of TResult
are you returning? Is the provided class supposed to define the type parameter of TResult
?
If the answer is yes to the last question, then you're probably looking for a declaration like this:
public static <T extends APIBaseEntity> TResult<T> getAllEntities(final Class<T> clazz, RouteFilter filter) {
//...
}
This basically forces the returned TResult<T>
to be of the same type T
as the provided clazz
: the type parameter of your method. This also removes the burden of casting to the return type you want, because the compiler now knows already.
Why do I have to point that T extends APIBaseEntity in getAllEntities method when it is already defined in TResult class signature?
If you write public <T> TResult<T> myMethod()
, T
is a generic type for your method, but is not constrained at all, so it could be anything. TResult<T>
does not act as a constraint for the type parameter of your method. You have to explicitly constrain it yourself, because you could even constrain it more than the TResult
class (for instance with a subtype of APIBaseEntity
).
If you don't constrain your method's type parameter, you get a compile error/warning (don't remember from the top of my head) because it wouldn't fit TResult
's type parameter declaration.
*Note: raw types are generic types referenced without their type parameter, such as Class
or TResult
, as opposed to Class<T>
or TResult<T>
.
Upvotes: 7