I have a class hierarchy (simplified) like:
Identifiable <- MemoOwner <- Antrag
which - BTW - represent DB entities.
I have a generic method which can fetch the entity type safe by the ID (done by hibernate):
public <T extends Identifiable> T getById(Class<T> clazz, Number id)
{
return (T) getSession().get(clazz, id);
}
In a business layer I have follwing method:
public MemoOwner loadMemoOwner(final int aId, final FinanzhilfeType aType)
{
Class<? extends MemoOwner> clazz = aType.getMemoOwnerClazz();
...
}
where the given FinanzhilfeType is an enum with associated member "MemoOwnerClazz" of type Class<? extends MemoOwner>. Depending on the type the final entity class can be different.
I would like call my generic method like (replacing above three dots):
return myLoggingDbService.getById(clazz, aId);
But eclipse compiler complains:
The method getById(Class<T>, Number) in the type PersistenceService is not applicable for the arguments (Class<capture#2-of ? extends MemoOwner>, int)
I overcomed this situation by using an if-cascade:
if ( clazz == Antrag.class )
{
return myLoggingDbService.getById(Antrag.class, aId);
}
if ( clazz == Vereinbarung.class )
{
return myLoggingDbService.getById(Vereinbarung.class, aId);
}
....
which is not really satisfying because it is not generic.
I understand that the java generics are a compile time construct. But I do not understand why the compiler does not accept the type "Class<? extends MemoOwner>" for the formal Class<T> parameter. IMO my desired call is type safe also at runtime, because
- hibernate instatiates the entity using given class (runtime dynamic)
- the instantiated class is always a descendant of type MemoOwner (compile time generics), and can be assigned to the return value of my business method.
Why the compiler doesn't accept this generic type?