Je ne suis pas sûr de comprendre le but de clone ()
dans ArrayList
.
Il existe de nombreuses façons de faire une copie superficielle d'un ArrayList
, j'en connais au moins deux:
ArrayList<Integer> AL1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4)); ArrayList<Integer> AL1_copy = (ArrayList<Integer>) AL1.clone();
Il est également surprenant que cela renvoie un Object
, au lieu d'un ArrayList
, Et je dois abattre:
List<Integer> L1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4)); List<Integer> L1_copy = new ArrayList<>(L1); List<Integer> L1_copy2 = List.copyOf(L1); // inmutable but solve by below: List<Integer> L1_copy3 = new ArrayList<>(List.copyOf(L1));
Pourquoi est-il conçu pour être renvoyé sous forme d'un Objet
?
Quel est l'avantage d'utiliser le clone par rapport à une autre méthode de copie superficielle?
3 Réponses :
Je ne pense pas qu'il y ait un avantage supplémentaire à cause de la présence de la méthode clone ()
. Dans le cas des primitives, cela équivaudrait à une copie profonde.
De plus, je ne connaissais pas ces nombreuses méthodes en Java sauf celle du constructeur, dans laquelle vous passez la Collection
comme argument dans le constructeur.
Il implémente également l'interface Cloneable
qui, je pense, est comme une interface de marqueur.
Il renvoie Object
car c'est la superclasse de toutes les classes et le renvoyer ne casserait pas le code.
Bien qu'il soit déclaré dans Object
, celui de Object
est protégé. ArrayList expose la méthode publiquement et fournit sa propre implémentation, qui fonctionne car la classe implémente Cloneable
.
même s'il ne le remplaçait pas, il serait toujours disponible.
S'il ne le remplaçait pas, la méthode serait protégée, donc non accessible au public.
Hmm. Merci. Je modifierai la réponse. J'ai oublié ce détail.
En général, une méthode publique clone () prend en charge le polymorphisme. Vous pouvez l'appeler sur une référence de type superclasse, pour cloner un objet de n'importe quel type de sous-classe.
Pourquoi est-il conçu pour être renvoyé en tant qu'objet?
Les types de retour covariants ont été introduits dans Java 5. ArrayList
a été introduit plus tôt, dans Java 2.
ArrayList
n'est pas une classe finale. La modification de son type de retour pour renvoyer ArrayList aurait pu interrompre des sous-classes tierces.
Y a-t-il un avantage à utiliser le clone par rapport à une autre méthode de copie superficielle?
Polymorphisme.
Le typage résulte de l'écriture de ArrayList avant java 5. Avant java 5, le type de retour d'une méthode de substitution devait être le même que la méthode qui était surchargée (était invariant ) . Aujourd'hui, comme les types de retour de méthode peuvent être spécialisés (sont covariants ), si ArrayList était en cours de réécriture, il devrait être écrit avec ArrayList comme type de retour.
Cependant, il y a un problème profond ici, qui est que si une implémentation peut spécialiser le type de retour de clone (), le système de types n'a pas pleinement exprimé la relation de typage. Ce qui serait mieux serait un type "self", que java ne prend en charge que marginalement. Cela vous amène assez profondément dans la théorie de la frappe. Voir, par exemple: Méthodes auto-typées Java: impossible diffuser en toute sécurité au type réel .
Du point de vue de l'utilité, comme d'autres l'ont dit, Cloneable s'est avéré ne pas être une API très utile. En pratique, il y a généralement trop de détails sur la façon dont on veut que la copie fonctionne pour qu'une seule API corresponde à tous ces détails.
Il met en œuvre le
Cloneable
, ce que quelqu'un a dû penser à un moment donné était une bonne idée. Ce n'est pas une interface très utile.c'est intéressant, y a-t-il des objets qui ne sont pas clonables?
Bien sûr. De nombreuses classes n'implémentent pas Cloneable.
cette méthode provient de la classe
Object
. Voir javadoc docs.oracle.com/ javase / 7 / docs / api / java / lang / Object.html # clon e ()Si vous voulez voir exactement comment ils implémentent clonable dans Arraylist, voici la source de Arraylist pour Java8 hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes /… a > Il semble simplement appeler Arrays.copyOf sur le backend. docs.oracle.com/javase/7/docs/api/java/util/...