J'ai les deux classes suivantes:
String className = new TypeToken<T>() {}.getClass().getName().toString();
Dans le Generic , j'ai une méthode dont j'ai besoin pour obtenir le nom de la classe qui est passée T
Est-ce possible en Java? Je sais qu'en C #, j'utiliserais simplement typeof.
J'ai essayé de faire ce qui suit:
class Generic<T>
{
}
class Foo extends Generic<Student>
{
}
Ceci cependant ne pas fournir le nom et ne fournit que Generic$1
4 Réponses :
Je suppose que Generic est toujours sous-classé avec une classe qui fournit le paramètre de type avec une classe réelle, comme dans le code Foo . Dans ce cas, les informations de type sont toujours disponibles en utilisant Class.getGenericSupertype . Voici un exemple rapide.
import java.lang.reflect.*;
class Generic<T>
{
public String name() {
Class<?> clazz = this.getClass();
for (;;) {
Class<?> superClass = clazz.getSuperclass();
if (superClass == null) {
throw new IllegalStateException();
}
if (superClass == Generic.class) {
Type genericSuper = clazz.getGenericSuperclass();
if (genericSuper instanceof ParameterizedType) {
ParameterizedType parameterized = (ParameterizedType)genericSuper;
Type[] params = parameterized.getActualTypeArguments();
if (params.length == 1) {
Type param = params[0];
if (param instanceof Class<?>) {
return ((Class<?>)param).getName();
}
}
}
throw new IllegalStateException();
}
clazz = superClass;
}
}
}
class Foo extends Generic<Student>
{
}
interface Student {}
interface Code {
static void main(String[] args) {
System.err.println(new Foo().name());
}
}
Cela ne concerne que des cas simples. Par exemple, si Foo étend Generic alors T n'est pas une Class.
Utilisez la méthode getGenericSuperclass () et vérifiez s'il s'agit d'un ParameterizedType puis récupérez tous les arguments avec getActualTypeArguments () qui renvoie un tableau Type , rappelez-vous qu'une classe générique peut utiliser plus d'un type comme Map (Map
C # et Java implémentent les génériques de manière très différente.
C # a de vrais génériques et des informations génériques au moment de l'exécution. Pour des raisons de compatibilité descendante, Java utilise l'effacement de type - c'est toute la magie générique qui se trouve dans le compilateur et il remplace Object par T partout et à l'exécution, vous n'avez aucune connaissance du type générique.
Les génériques Java sont toujours meilleurs que les modèles C ++, ce qui n'est pas mieux que la substitution de macros à la compilation. Mais Java ne peut pas faire de génériques de style C # sans rompre la rétrocompatibilité avec l'ancienne version de runtime / bytecode.
En résumé, vous ne pouvez pas faire cela en Java.
Le moyen facile d'obtenir le nom d'une classe générique.
Définir une classe générique
public void exampleMethod(GenericClass type) {
String fullName= type.getType().getCanonicalName(); //"com.example.MyEntity"
String sortName= type.getType().getSimpleName(); //"MyEntity"
}
}
Utilisez cette classe générique comme un paramètre
GenericClass type = new GenericClass(MyEntity.class); exampleMethod(type);
Dans la méthode exampleMethod
public class GenericClass<T> {
private final Class<T> type;
public GenericClass(Class<T> type) {
this.type = type;
}
public Class<T> getType() {
return this.type;
}
Cochez ceci stackoverflow.com/questions/6624113/...
Vous ne pouvez pas utilement créer un jeton de type générique. Vous pouvez obtenir la classe à partir d'un jeton de type non générique (par exemple,
new TypeToken () {} ounew TypeToken) en regardant les paramètres de type de son supertype générique; mais ce paramètre de type est la variable de type T pour ce jeton de type.> () {}
J'ai rouvert car ce n'est pas une copie de la question revendiquée. Dans ce cas, le type est accessible via
Foo(bien qu'il y ait une exigence que la sous-classe n'utilise pas de paramètre ici).