Appel de la méthode Générique de type de retour en Java
En C++, vous pouvez spécifier le type de retour d'une fonction à un paramètre, tel que:
C++
float* myFloat = CollectionClass.ptr<float>();
int* myInt = CollectionClass.ptr<int>();
Est-il un équivalent en Java pour spécifier le type de retour, sans ajout supplémentaire de classe args?
Java
//This doesn't work (due to type erasure)
public <T> T getDate()
{
if (T instanceof Date)
return new Date();
if (T instanceof Calendar)
return new Calendar();
}
Date myDate = getDate<Date>();
qu'est-ce acheter de vous que vous ne pourriez pas accomplir par simplement jeter le plus générique, le retour à une plus spécifiques var?
mise à jour de la question pour être plus clair
mise à jour de la question pour être plus clair
OriginalL'auteur Jason | 2013-02-27
Vous devez vous connecter pour publier un commentaire.
Il est parfaitement bien de déclarer une méthode avec la signature
public <T> T getDate()
.Cependant, il est impossible de mettre en œuvre la méthode qui renvoie ce que vous voulez. Quelle méthode ne au moment de l'exécution ne peut pas compter sur son paramètre de type seul, car il ne sait pas son paramètre de type.
Pour obtenir une intuition pour cela, se rendre compte que tout le code écrit avec les génériques peuvent également être écrit de manière équivalente, sans l'aide de médicaments génériques, en retirant simplement les paramètres génériques et de l'insertion de jette, le cas échéant. C'est ce type "d'effacement".
Donc, pour voir si votre méthode serait possible dans les Génériques, il suffit de demander, comment voulez-vous le faire sans les Génériques:
Si vous ne pouvez pas le faire sans les Génériques, vous ne pouvez pas le faire avec les Génériques.
Modèles C++ sont complètement différents. Pour basé sur un modèle de fonctions et de classes, les modèles C++ génère une "copie" de la fonction ou de la classe pour chaque type d'argument qui est utilisé. c'est à dire le compilateur prend l'basées sur des modèles de code, "copie et colle le" il en de multiples versions, chacune séparée. Par conséquent, chaque exemplaire de ce code est spécifique à un certain type d'argument, et peut donc utiliser ce type à l'exécution.
C'est pourquoi C++ basé sur un modèle de code doit être disponible sous forme de code source afin que vous puissiez l'utiliser, il n'y a pas une telle chose comme "compilé" modèles. Toutefois, en Java, un compilé de classe générique peut être utilisé. Générique de classes et de méthodes en Java ne pas supposer quoi que ce soit sur les types qu'ils peuvent être utilisés sur.
OriginalL'auteur newacct
Bon, maintenant, à le modifier pour le rendre clair que le code est subordonnée à
T
...Non, il n'y a rien de simple dans Java pour faire ce travail - en raison du type d'effacement, comme votre question mentionne. Vous pouvez passer en
Class<T>
:... mais vous ne pouvez pas faire rien qui dépend de la "valeur" de
T
lui-même au moment de l'exécution, que ce n'est tout simplement pas connu. Les génériques est un peu anémique en Java, malheureusement 🙁EDIT: Avant de le modifier pour rendre le code conditionnel sur
T
...C'est juste une question de spécifier le type de l'argument différemment:
J'ai toujours préféré les "mettre les arguments de type juste avant le des arguments régulièrement" l'approche de trop, mais allons-y...
EDIT: Comme rgettman points, l'inférence de type va faire la bonne chose pour vous de toute façon, ici, de sorte que vous n'avez pas réellement besoin de spécifier le type des arguments, dans de nombreux cas. Parfois, vous faites bien.
Date date = Test.getDate();
en fait, il fonctionne très bien dans votre code ci-dessus.quel serait le but de le faire de cette façon que tu ne pouvais pas faire si
getDate
simplement retourné Date? quelle est l'utilisation de médicaments génériques acheter vous dans ce cas?Plus d'une question de Jason que Jon, n'est-ce pas? (Mais Jason est mise à jour à la question clarifie les choses...)
Bon point. Modifier - en particulier avec le bit sur l'inférence.
OriginalL'auteur Jon Skeet
Avec
Arrays.asList
, il est parfois nécessaire de spécifier le type de retour. Java tente de "réduire" le type de retour fondées sur la commune supertype(s) de tous les arguments, mais parfois vous avez besoin d'un type spécifique. Par exemple,Ici,
Arrays.asList
renvoie uneList<Integer>
et vous obtenez une erreur du compilateur. Pour obtenir le retour d'unList<Number>
, vous devez spécifier le type générique.OriginalL'auteur rgettman