8
votes

Java Noob: génériques sur des objets uniquement?

Je suis nouveau à Java. Tout en codant une carte <>, j'ai découvert que déclarer mapper est une erreur de syntaxe tandis que mapper est ok. Est-ce seulement possible dans Java d'instancier des génériques sur les types d'objets, par opposition aux primitives? Si tel est le cas, existe-t-il une pénalité de performance notable pour la boxe / la boîteboxing des primitives?


1 commentaires

Comme les autres ont indiqué, il existe une pénalité de performance définie. Cependant, il y a une grande différence entre les outils perceptibles aux outils de profilage et perceptibles des utilisateurs.


4 Réponses :


11
votes

Oui, vous ne pouvez utiliser que des types de référence uniquement pour les paramètres de type générique, et oui, une pénalité de performance sera due à la boxe / débattre (qui peut être effectuée automatiquement pour la plupart).

Voici une citation du FAQ de Java Generics :

sont des types primitifs autorisés comme des arguments de type?

non. Seuls les types de référence peuvent être utilisés comme arguments de type. Un type paramétré tel que la liste ou définir est illégal. Seuls les types de référence peuvent être utilisés pour l'instanciation des types et des méthodes génériques. Au lieu de Liste Nous devons déclarer une liste , à l'aide du type d'emballage correspondant comme argument de type.

[...] note que le manque d'instanciations de type primitif entraîne une pénalité de performance. AutoBoxing et -unboxing permettent d'utiliser des instanciations de type wrapper de types génériques très pratiques et concises dans le code source. Mais la notation concise cache le fait que derrière le rideau, la machine virtuelle crée et utilise de nombreux objets d'emballage, chacun doit être attribué et recueillir ultérieurement. Les performances plus élevées d'utilisation directe des valeurs de type primitif ne peuvent pas être obtenues avec des types génériques. Seul un type régulier peut fournir les performances optimales de l'utilisation de valeurs de type primitif.

Si vous avez absolument besoin de la performance, Trove a de nombreuses structures de données spécialisées pour les types primitifs, mais pour la plupart pratiques Des objectifs, en utilisant des types de primitifs boxés avec des classes de collections Java Collections devraient donner plus que des performances acceptables.

Voir aussi


0 commentaires

2
votes

n'est-ce que possible dans Java de Instanciez les génériques sur l'objet types, par opposition aux primitives?

correct.

Si oui, est-il une notable pénalité de performance pour boxe / décomposition des primitives?

Oui, il y a.

voir ici pour une description détaillée: http: //java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html


0 commentaires

2
votes

1) Oui, les génériques Java ne fonctionnent que sur les types d'objets. Cela est dû à la manière dont ils sont implémentés, ce qui se passe par Type Erasure - essentiellement, une fois que cela est compilé à ByTecode, tous les types génériques sont remplacés par objet - ceci a été fait pour que Java Generics puisse fonctionner sans modifier le JVM / bytecode sous-jacent (mauvaise décision, IMO ).

2) Oui, il y aura une pénalité de boxe / de construction; Ne peut pas être évité, j'ai peur.


0 commentaires

0
votes

Comme d'autres l'ont noté, il y a une pénalité de performance pour l'utilisation de classes d'emballage pour les primitives. Et même si le coût n'est pas vraiment perceptible, si vous avez vraiment besoin du boost de performance supplémentaire, vous pouvez simplement créer des sous-classes personnalisées pour la classe de liste, une pour chaque type primitif (ils ne sont pas nombreux, ce n'est pas un problème) et simplement de remplacer les méthodes Cela mettez et obtenez des valeurs dans la liste et limitez-les à accepter chaque primitive. Cela entraînera le renforcement des performances et conservera la verbosité du code de liste générique.


2 commentaires

Implémentation Liste en soi n'apportera pas un gain de performance car l'interface publique nécessitera toujours une boxe. Vous auriez besoin de surcharge (pas remplacement ) toutes les méthodes et si vous faites cela, pourquoi implémenter Liste en premier lieu?


Ce que j'avais à l'esprit consistait à sous-classer une implémentation de la liste concrète telle que LinkedList. Vous pouvez sous-classe LinkedList Et fournir des méthodes "Wrapper" pour ajouter et récupérer des INT au lieu d'entiers, par exemple ...