Typparameter einer generischen java-Klasse zur Laufzeit bestimmen
Einer der etwas komplizierten Teile von Java generics ist der Umgang mit Typparametern zur Laufzeit.
Oftmals wird behauptet, dass es nicht möglich sei, den konkreten Typ eines Typ-Parameters zur Laufzeit zu erhalten. Das stimmt so aber nicht.
Nehmen wir folgende Klassen, wobei Entity und EntityImpl unwichtiger Beispielcode sind:
/**
* Demonstrates the retrieval of a generic type parameters actual Class at runtime.
*
* @author Olaf Otto
*
* @param <T> the generic type.
*/
public abstract class AbstractDao<T extends Entity> {
@SuppressWarnings("unchecked")
public void foo() {
Class<T> clazz = null;
// Since we are targeting this class, we know it is a ParameterizedType.
// We use getGenericSuperclass in this example since this class is abstract and the method will be invoked
// on a directly derived class instance.
ParameterizedType pt = (ParameterizedType) getClass().getGenericSuperclass();
Type[] typeArguments = pt.getActualTypeArguments();
// Since we know the maximum number of type arguments (1), this check is sufficient.
if (typeArguments != null && typeArguments.length > 0) {
Type arg = typeArguments[0];
if (arg instanceof Class) {
clazz = (Class<T>) arg;
}
}
System.out.println("Resolved generic type parameter to " + clazz + ".");
}
}
/**
* Dummy class for demonstration purposes.
*/
public class Entity {
}
/**
* Dummy class for demonstration purposes.
*/
public class SomeEntity extends Entity {
}
Ruft man jetzt innerhalb einer main-Methode oder eines Unit-Tests die Methode foo() auf einer SomeEntity-Instanz auf, so erhält man folgendes Ergebnis:
Resolved generic type parameter to class my.package.name.SomeEntity.
Womit der Typparameter korrekt aufgelöst ist.
Zum Ausprobieren: die verwendete Main-Klasse.
/**
* A main method provider for demonstration purposes.
*/
public class Main {
public static void main(String[] args) {
SomeEntityDao dao = new SomeEntityDao();
dao.foo();
}
}
Pro und contra
In einem Ähnlichen Posting zeigt Ian Robertson, wie man diese Systematik unabhängig von der Vererbungshierarchie verwenden kann.
In den Kommentaren zu seinem Posting wird diskutiert, warum man überhaupt so viel komplizierten utility-Code schreiben sollte, wenn man ebensogut einfach und sicher die Klasse des Typ-Parameters in der ableitenden Klasse bekannt machen kann – was letztendlich davon abhängt, an wie vielen unterschiedlichen Stellen im Code man die Typinformationen der Parameter benötigt.
API Dokumentationen zum Posting:
Die ParameterizedType API-Dokumentation
This entry was posted on Tuesday, March 25th, 2008 at 16:04. Posted in: System architecture, generics, java. You can follow any responses to this entry through the RSS 2.0feed. You can leave a response, or trackback from your own site.
