java generics: Formal type "? extends MyClass" cannot be used for a call to "T get(Class<T> aClass)

Viewed 52

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?

0 Answers
Related