Est-il possible d'utiliser les médicaments génériques dans les listes en Java 1.4?

StackOverflow https://stackoverflow.com/questions/6320313

  •  27-10-2019
  •  | 
  •  

Question

Je dois utiliser Java 1.4 et je utilise des structures ArrayList. Maintenant, je dois faire une refactoring et il serait utile que je peux utiliser Generics. À l'heure actuelle, j'ai le code comme ceci

ArrayList rows = new ArrayList();

Ce qui est un ArrayList simple. Mais maintenant, la « lignes » variable est de plus en plus complexe et la nécessité de définir une classe « Row ». Je veux maintenant faire quelque chose comme ce que vous voyez dans J2SE 1.5

ArrayList<Row> rows = new ArrayList();

Un chalut par Google n'expose pas de réponses sans une utilisation sophistiquée de solutions 3ème partie. Comment mon code à changer pour accueillir ce en 1.4, sans utiliser des solutions 3ème partie / projets open source, (si possible)?

Était-ce utile?

La solution

Génériques ont été introduites dans JDK 1.5. Donc, vous ne pouvez pas les utiliser dans 1.4. Toutefois, vous pourrez peut-être utiliser le compilateur JDK 1.5 mais 1.4 cible avec vos classes avec l'option -target 1.4 javac tout en gardant l'option -source 1.5 pour indiquer que votre source est compatible 1.5. Dans ce cas, vous pouvez utiliser les médicaments génériques car ils ne devraient pas affecter les classes de résultats.

Voir la section sur les options de compilation croisée

Autres conseils

Génériques tend à résoudre le problème de ce que je considère « naïfs » moulages en Java 1.4 ou plus tôt lorsqu'ils traitent avec les collections. En Java 1.5+, la ligne que vous avez placé:

ArrayList<Row> rows = new ArrayList();

donnerait un avertissement, le code générique approprié est

ArrayList<Row> rows = new ArrayList<Row>();

Cela indique au compilateur que votre objet ArrayList ne doit contenir que soit le type de ligne.

Cependant, depuis Java 1.5 est rétrocompatible avec les jeux énormes de bibliothèques qui ne contiennent pas cette syntaxe, mais plutôt votre code précédent:

ArrayList rows = new ArrayList();

Génériques évidemment ne fonctionnerait pas avec ces anciennes bibliothèques - donc génériques ne sont que compilation l'option - 1,5 et 1,4 classes sont effectivement équivalentes (moins tout refactoring interne / nouvelles méthodes ajoutées plus tard) car ils sont vraiment mises en œuvre ArrayList qui gèrent tout type d'objet.

Le code 1.5 ajoute simplement une distribution directe pour vous.

Dans la version 1.4 du code, que vous vouliez parcourir la ArrayList. La façon de casting naïf de le faire est le suivant:

for(Iterator rowIterator = rows.iterator(); rowIterator.hasNext(); ) {
    Row row = (Row) rowIterator.next();
    // Do something with the row.
}

code de Java 1.5 est exactement équivalente à la version moulée naïve. Il faut le fait que vous dites au compilateur que une ligne et bien ce code pour vous. Ainsi, les avantages de sucre syntaxique sont plus agréables (celui-ci utilise la plus récente pour chaque syntaxe de la boucle, mais il génère le même code que la boucle ci-dessus):

for(Row row : rows) {
   // Do something with the row
}

Donc, si vous voulez utiliser une ArrayList contenant uniquement les lignes, vous pouvez toujours. Mais il n'y a pas moyen d'obtenir le compilateur chèque que le ArrayList ne contient que toutes les lignes (bien que, même si le compilateur fournit cette vérification, il est encore possible pour envoyer dans un ArrayList qui contient d'autres types d'objets, car, encore une fois, le ArrayList encore ne gère que vraiment le type d'objet, et les génériques sont effacés lors de l'exécution -. tout ce qui reste est le code coulé naïf que vous ne voyez pas plus)

La variante non naïve est de vérifier chaque cas et jeter un ClassCastException vous avec un message d'information (plutôt que de celui de lancer de programme avec son message par défaut):

for(Iterator rowIterator = rows.iterator(); rowIterator.hasNext(); ) {
    Object shouldBeRow = rowIterator.next();
    if(!(shouldBeRow instanceof Row)) {
        throw new ClassCastException("The object " + shouldBeRow + " is not an instance of Row - only Rows should be present in the list!");
    }
    Row row = (Row) shouldBeRow;
    // Do something with the row.
}

Cependant, en général ne fait cela -. Une bonne documentation en faire sans objet question, car elle impose la charge de fournir la collecte correcte sur l'appelant et vous pouvez donc avoir juste la ClassCastException lancée par la machine virtuelle Java

Oui, vous pouvez. Utilisez un compilateur 1.5, et l'utilisation

javac -target jsr14 ............

Cela va générer java 1.4 classes, mais permettent des génériques.

Ce commutateur ne peut être utilisé pour le code non octet 1.5 visibles caractéristiques. Par exemple, vous ne pouvez pas utiliser énumérations ou de nouvelles méthodes introduites dans 1,5. Mais les médicaments génériques sont très bien, car ils ne sont pas vraiment présents dans le code d'octets.

Non, vous ne pouvez pas les utiliser dans JDK 1.4. Ils ont été introduits dans JDK1.5

Tout ce que vous avez à faire est de les jeter. Cela pourrait mériter une exception d'exécution si vous mettez types « mauvais » dans la liste.

Row arow = (Row) rows.get(0);

for ($i=0; i<rows.size(); $i++){
    Row element = (Row) rows.get($i);
    element.printCells();
    (...)
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top