J'ai remarqué que dans Java Cependant, il est surprenant qu'il n'y a pas de version générique équivalente de cela. Java 7's Depuis la mise en œuvre de Cela semble trivial, y a-t-il une raison de ne pas l'ajouter dans la JRE? ou je ne peux tout simplement pas en trouver un? p> update strong> p> Il semble que je fournisse ma propre implémentation "triviale" pour arrêter le malentendu de la question. P > Array.Newinstance () Code> retour objet code>, plutôt que t [] code>. Il est compréhensible car cette méthode a été introduite avant que Java prend en charge les types génériques. class MyArrayUtil {
//Generic version for classes
@SuppressWarnings("unchecked")
public static <T> T[] newArrayOf(T[] t, int len){
return (T[]) Array.newInstance(t.getClass().getComponentType(), len);
}
//For array of int
public static int[] newArrayOf(int[] t, int len){
return new int[len];
}
//For other primitive types...
}
3 Réponses :
Non, vous devez transmettre le type de béton comme un paramètre d'une manière ou d'une autre. Comme vous l'avez mentionné, arranges.copyof code> montre ceci en action. Class<T> type = determinteTheTypeSomehow();
return (T[]) Array.newInstance(type, length);
array.newinstance code> nécessite une classe <> code>, comme arrangé.copyof code> nécessite t [] code>, alors ils le font nécessite un paramètre supplémentaire plutôt qu'un paramètre de type. Je me demande simplement pourquoi nous ne pouvons pas avoir de class t [] code> (en tant que modèle uniquement; contenu à l'intérieur est ignoré).
Oui, je comprends, mais vous essayez de plier l'API à vos besoins qui ne fonctionneront jamais;) J'admise que cela peut être frustrant cependant c'est comme ça.
Lorsque j'écris des types de génériques, je passe souvent dans le type de paramètre concret comme un argument du constructeur pour ces objectifs (et autres).
GUAVA fournit Une telle fonction . Ce n'est pas la première fois que Guava (ou Apache Commons) a fourni une aide couramment utilisée que le JDK n'a pas, pour une raison quelconque.
Vous pouvez le savoir, mais certains de fond pour le googler qui trébuchent sur cela à l'avenir. : La raison pour laquelle la signature ne peut pas être rendue générique est que la méthode ... alors le type de retour serait the array.newinstance code> Retour Objet Code> dans Java 1.4 , Donc, pour la compatibilité en arrière, la version brute de la méthode doit également renvoyer objet code>. S'il avait été génendu comme: p> objet [] code>, pas objet code >. Cela briserait la compatibilité à l'envers, que les concepteurs Java ont toujours essayé très fort de ne pas le faire. P> des tableaux.Copyof code> est entré uniquement avec Java 1.6, et donc n'a donc pas se soucier de la compatibilité en arrière. p> p>
Maintenant, je pense que je comprends bien pourquoi il n'a pas beaucoup de sens d'avoir Newarray code> prend en charge les types primitifs. Si vous souhaitez créer un nouveau tableau avec des types qui ne sont pas un paramètre de type générique, vous pouvez simplement utiliser nouveau xyz [] code>. Si ce n'est pas le cas, vous devez utiliser le type de classe et que dans ce cas, le Newarray code> est utile.
Cela ne devrait pas être un problème si vous avez besoin d'un paramètre / champ similaire dans votre méthode Signature / Classe Définition.
@Arthengine En outre, il fonctionne pour des types primitifs, car int.class code> existe (et de même pour les autres primitives). Voir Ideone.com/ATVBJX pour un exemple.
Je sais que c'est possible. Mais cela n'a aucun sens si vous avez une classe classe > Code> d'instance à l'exécution. Et dans ce cas, votre code utilise explicitement la réflexion, pas seulement générique.
Étant donné que la modification du type de retour effacé de objet code> à objet [] code> est un rétrécissement, il devrait au moins en théorie être compatible Binaire.
la raison de base que sûr, ils auraient pu em> ajouter une méthode supplémentaire comme array.newinstance () code> ne peut pas être déclaré comme int.class code>, qui a le type classe integer [ ] code> objet. Cependant, la fonction renvoie réellement un objet int [] code>, qui n'est pas un sous-type de entier [] code>, il a donc le mauvais type. P>
NewreFerenceArrayInstance () code> qui interdit les types primitifs (par exemple, jette une exception lorsqu'il est passé un type primitif) et peut donc être déclaré en toute sécurité Pour retourner t [] code>. Cependant, cela semble être ajouté une méthode complètement redondante uniquement pour éviter une coulée non cochée. P>
Non, il est impossible de mettre en œuvre cela dans une mode de sécurité de type compacuation. Par exemple, vous ne pouvez pas créer une nouvelle instance d'une liste: [] code>. Le compilateur ne saura jamais ce que le type de
t code> est, et il ne peut donc pas garantir que le code client est sûr.Depuis
Arrays.Copyof CODE> peut faire le travail Il n'y a aucune raison évidente que vous ne pouvez pas.Arrays.copyof code> détermine le type de béton de la matrice à copier.Donc, cela va bien d'avoir un
similaire.newinstanceof code> qui utilise un type concret pour fournir des informations de type, et comme ce que j'ai dit dans la question, cette mise en œuvre est triviale.Sorte d'un poulet dans le problème de l'œuf avec votre méthode. Afin de créer un tableau, je dois déjà avoir déjà instancié un tableau du type donné. À ce moment-là, je ne peux que Nouveau moi-même. Votre méthode n'offre aucun avantage sur l'existant.
Essayez: T [] NewInstance (Classe Clazz, Int Longueur) Je suis sur mon téléphone, je ne peux pas tester. Jetez un coup d'œil à angelikalanger.com/genericsfaq/javagenericsfaq.html Aussi
@Kyle Vous avez raison si j'ai une méthode comme la vôtre, cela peut être plus utile. Cependant, cela ne signifie pas que la mienne n'a aucun moyen d'utiliser. Supposons simplement que vous souhaitiez simplement écrire un code générique qui réorganise (doubler le côté, la souffrant, etc.) un tableau existant.
FWIW, GUAVA fournit Juste une telle méthode .
@yshavit Vous obtenez le plus proche de la réponse ... Pouvez-vous continuer et poster votre réponse? Quoi qu'il en soit, les tableaux de Guava semble ne pas prendre en charge les types primitifs.
@yshavit a également trouvé la réponse que vous venez de supprimer a du sens sur le raisonnement. Pouvez-vous la restaurer et ajouter la référence GUAVA et en discuter? Cela semble être une réponse acceptable.
@Arthengine juste fait, merci. :)
Pourquoi pas simplement utiliser
arrayes.copyofrange (t, t.length, t.length + len) code>?@Jules car il exige que vous ayez une instance existante en main, mais
NewInstance code> n'exige rien.