reflexivité - type class java




Pourquoi la classe Java Vector est-elle considérée comme obsolète ou obsolète? (4)

Le vecteur faisait partie de 1.0 - la mise en œuvre originale avait deux inconvénients:

1. Nommage: les vecteurs ne sont en réalité que des listes accessibles en tableaux, donc cela aurait dû s'appeler ArrayList (qui est le remplacement des collections Java 1.2 pour Vector ).

2. Concurrence: Toutes les méthodes get() , set() sont synchronized , vous ne pouvez donc pas avoir un contrôle précis de la synchronisation.

Il n'y a pas beaucoup de différence entre ArrayList et Vector , mais vous devriez utiliser ArrayList .

À partir du document API

À partir de la version 1.2 de la plate-forme Java 2, cette classe a été ajoutée pour implémenter l'interface List, ce qui en fait un membre du framework de collections Java. Contrairement aux nouvelles implémentations de collection, Vector est synchronisé.

Pourquoi Java Vector est-il considéré comme une classe héritée, obsolète ou obsolète?

Son utilisation n'est-elle pas valide lorsque vous travaillez avec la concurrence?

Et si je ne veux pas synchroniser manuellement les objets et que je veux juste utiliser une collection thread-safe sans avoir besoin de faire de nouvelles copies du tableau sous-jacent (comme le fait CopyOnWriteArrayList ), alors est-ce bien d'utiliser Vector ?

Qu'en est-il de Stack , qui est une sous-classe de Vector , que dois-je utiliser à la place?


Outre les réponses déjà mentionnées sur l'utilisation de Vector, Vector propose également un ensemble de méthodes de numérotation et de récupération d'éléments différentes de celles de List. Les développeurs (en particulier ceux qui ont appris Java avant 1.2) ont tendance à les utiliser code. Bien que les énumérations soient plus rapides, elles ne vérifient pas si la collection a été modifiée pendant l'itération, ce qui peut causer des problèmes et étant donné que Vector pourrait être choisi pour sa synchronisation - avec l'accès de plusieurs threads, cela en fait un problème particulièrement pernicieux. L'utilisation de ces méthodes couple également beaucoup de code à Vector, de sorte qu'il ne sera pas facile de le remplacer par une implémentation List différente.


Vector synchronise sur chaque opération individuelle. Ce n'est presque jamais ce que vous voulez faire.

Généralement, vous voulez synchroniser toute une séquence d'opérations. La synchronisation des opérations individuelles est à la fois moins sûre (si vous itérez sur un Vector , par exemple, vous devez encore retirer un verrou pour éviter que quelqu'un d'autre ne change la collection en même temps, ce qui provoquerait une ConcurrentModificationException dans le thread itéré). plus lent (pourquoi sortir une serrure à plusieurs reprises quand une fois sera suffisant)?

Bien sûr, il a également les frais généraux de verrouillage, même lorsque vous n'en avez pas besoin.

Fondamentalement, c'est une approche très imparfaite de la synchronisation dans la plupart des situations. Comme l'a souligné M. Brian Henk , vous pouvez décorer une collection en utilisant les appels tels que Collections.synchronizedList - le fait que Vector combine à la fois l'implémentation de la collection "resized array" avec le bit "synchronize every operation" est un autre exemple de mauvaise conception; l'approche de la décoration permet une séparation plus nette des préoccupations.

Quant à un équivalent Stack - je regarderais ArrayDeque / ArrayDeque pour commencer.


java.util.Stack hérite de la surcharge de synchronisation de java.util.Vector , ce qui n'est généralement pas justifié.

Il hérite beaucoup plus que cela, cependant. Le fait que java.util.Stack extends java.util.Vector est une erreur dans la conception orientée objet. Les puristes remarqueront qu'il offre aussi beaucoup de méthodes au-delà des opérations traditionnellement associées à une pile (à savoir: pousser, pop, peek, taille). Il est également possible de faire des search , elementAt , setElementAt , remove , et bien d'autres opérations à accès aléatoire. C'est essentiellement à l'utilisateur de s'abstenir d'utiliser les opérations non-stack de Stack .

Pour ces raisons de performances et de conception OOP, JavaDoc pour java.util.Stack recommande ArrayDeque comme remplacement naturel. (Une deque est plus qu'une pile, mais au moins c'est limité à manipuler les deux extrémités, plutôt que d'offrir un accès aléatoire à tout.)





obsolete