t
t
t
t
t t   9) Stockage des objets
tttt
t
carrea) Préface carreb) Avant-propos carre1) Introduction sur les &laqo; objets » carre2) Tout est &laqo; objet » carre3) Contrôle du flux du programme carre4) Initialization & Cleanup carre5) Cacher l'implémentation carre6) Réutiliser les classes carre7) Polymorphisme carre8) Interfaces & classes internes 9) Stockage des objets carre10) Error Handling with Exceptions carre11) Le système d’E/S de Java carre12) Identification dynamique de type carre13) Création de fenêtres & d'Applets carre14) Les &laqo; Threads » multiples carre15) Informatique distribuée carreA) Passage et retour d'objets carreB) L'Interface Java Natif (JNI) carreC) Conseils pour une programation stylée en Java carreD) Resources
Texte original t Traducteur : Jérome Quelin
t
t
///
Ce chapitre contient 14 pages
1 2 3 4 5 6 7 8 9 10 11 12 13 14
\\\
t t t
t t t
t
t t t
The classes Cat and Dog are distinct—they have nothing in common except that they are Objects. (If you don’t explicitly say what class you’re inheriting from, you automatically inherit from Object.) Since ArrayList holds Objects, you can not only put Cat objects into this container using the ArrayList method add( ), but you can also add Dog objects without complaint at either compile-time or run-time. When you go to fetch out what you think are Cat objects using the ArrayList method get( ), you get back a reference to an object that you must cast to a Cat. Then you need to surround the entire expression with parentheses to force the evaluation of the cast before calling the print( ) method for Cat, otherwise you’ll get a syntax error. Then, at run-time, when you try to cast the Dog object to a Cat, you’ll get an exception.
t Les classes Cat et Dog sont distinctes - elles n'ont rien en commun sinon le fait que ce sont des Objects (dans le cas où une classe ne spécifie pas de classe de base, elle hérite automatiquement de la classe Object). Comme l'ArrayList contient des Objects, on peut stocker aussi bien des objets Cat que des objets Dog via la méthode add() sans aucune erreur, aussi bien lors de la compilation que lors de l'exécution du programme. Par contre, lorsqu'une référence sur ce qu'on pense être un Cat est extraite via la méthode get() de ArrayList, il faut la transtyper en Cat. Pour éviter une erreur de syntaxe, il faut entourer l'expression par des parenthèses pour forcer l'évaluation du transtypage avant d'appeler la méthode print() de Cat. Mais à l'exécution, lorsqu'on tente de transtyper un objet Dog en Cat, la machine virtuelle Java générera une exception.
t t t
This is more than just an annoyance. It’s something that can create difficult-to-find bugs. If one part (or several parts) of a program inserts objects into a container, and you discover only in a separate part of the program through an exception that a bad object was placed in the container, then you must find out where the bad insert occurred. On the upside, it’s convenient to start with some standardized container classes for programming, despite the scarcity and awkwardness.
t Ceci est plus qu'ennuyeux. Cela peut mener de plus à des bugs relativement durs à trouver. Si une partie (ou plusieurs parties) du programme insère des objets dans le conteneur, et qu'on découvre dans une partie complètement différente du programme via une exception qu'un objet du mauvais type a été placé dans le conteneur, il faut alors déterminer où l'insertion coupable s'est produite. Cependant, il est pratique de démarrer avec les classes conteneur standard pour programmer, en dépit de leurs limitations et de leur lourdeur.
t t t

Sometimes it works anyway

t

Quelquefois ça marche quand même

t t t
It turns out that in some cases things seem to work correctly without casting back to your original type. One case is quite special: the String class has some extra help from the compiler to make it work smoothly. Whenever the compiler expects a String object and it hasn’t got one, it will automatically call the toString( ) method that’s defined in Object and can be overridden by any Java class. This method produces the desired String object, which is then used wherever it was wanted.
t Dans certains cas les choses semblent fonctionner correctement sans avoir à transtyper vers le type originel. Un cas particulier est constitué par la classe String que le compilateur traite de manière particulière pour la faire fonctionner de manière idoine. Quand le compilateur attend un objet String et qu'il obtient autre chose, il appellera automatiquement la méthode toString() définie dans Object et qui peut être redéfinie par chaque classe Java. Cette méthode produit l'objet String désiré, qui est ensuite utilisé là où il était attendu.
t t t
Thus, all you need to do to make objects of your class print is to override the toString( ) method, as shown in the following example:
t Il suffit donc de redéfinir la méthode toString() pour afficher un objet d'une classe donnée, comme on peut le voir dans l'exemple suivant :
t t t
//: c09:Mouse.java // Overriding toString(). public class Mouse { private int mouseNumber; Mouse(int i) { mouseNumber = i; } // Override Object.toString(): public String toString() { return "This is Mouse #" + mouseNumber; } public int getNumber() { return mouseNumber; } } ///:~ //: c09:WorksAnyway.java // In special cases, things just // seem to work correctly. import java.util.*; class MouseTrap { static void caughtYa(Object m) { Mouse mouse = (Mouse)m; // Cast from Object System.out.println("Mouse: " + mouse.getNumber()); } } public class WorksAnyway { public static void main(String[] args) { ArrayList mice = new ArrayList(); for(int i = 0; i < 3; i++) mice.add(new Mouse(i)); for(int i = 0; i < mice.size(); i++) { // No cast necessary, automatic // call to Object.toString(): System.out.println( "Free mouse: " + mice.get(i)); MouseTrap.caughtYa(mice.get(i)); } } } ///:~ t
//: c09:Mouse.java
// Redéfinition de toString().
public class Mouse {
  private int mouseNumber;
  Mouse(int i) { mouseNumber = i; }
  // Redféinition de Object.toString():
  public String toString() {
    return "This is Mouse #" + mouseNumber;
  }
  public int getNumber() {
    return mouseNumber;
  }
} ///:~

//: c09:WorksAnyway.java
// Dans certains cas spéciaux, les choses
// semblent fonctionner correctement.
import java.util.*;

class MouseTrap {
  static void caughtYa(Object m) {
    Mouse mouse = (Mouse)m; // Transtypage depuis un Object
    System.out.println("Mouse: " +
      mouse.getNumber());
  }
}

public class WorksAnyway {
  public static void main(String[] args) {
    ArrayList mice = new ArrayList();
    for(int i = 0; i < 3; i++)
      mice.add(new Mouse(i));
    for(int i = 0; i < mice.size(); i++) {
      // Aucun transtypage nécessaire, appel
      // automatique à Object.toString() :
      System.out.println(
        "Free mouse: " + mice.get(i));
      MouseTrap.caughtYa(mice.get(i));
    }
  }
} ///:~
t t t
You can see toString( ) overridden in Mouse. In the second for loop in main( ) you find the statement:
t La méthode toString() est redéfinie dans Mouse. Dans la deuxième boucle for de main() on peut voir l'instruction :
t t t
System.out.println("Free mouse: " + mice.get(i)); t
System.out.println("Free mouse: " + mice.get(i));
t t t
After the ‘+’ sign the compiler expects to see a String object. get( ) produces an Object, so to get the desired String the compiler implicitly calls toString( ). Unfortunately, you can work this kind of magic only with String; it isn’t available for any other type.
t Après le signe « + » le compilateur s'attend à trouver un objet String. get() renvoie un Object, le compilateur appelle donc implicitement la méthode toString() pour obtenir l'objet String désiré. Cependant, ce comportement magique n'est possible qu'avec les String, il n'est pas disponible pour les autres types.
t t t
A second approach to hiding the cast has been placed inside MouseTrap. The caughtYa( ) method accepts not a Mouse, but an Object, which it then casts to a Mouse. This is quite presumptuous, of course, since by accepting an Object anything could be passed to the method. However, if the cast is incorrect—if you passed the wrong type—you’ll get an exception at run-time. This is not as good as compile-time checking but it’s still robust. Note that in the use of this method:
t Une seconde approche pour cacher le transtypage est de le placer dans la classe MouseTrap. La méthode caughtYa() n'accepte pas une Mouse mais un Object, qu'elle transtype alors en Mouse. Ceci ne fait que repousser le problème puisqu'en acceptant un Object on peut passer un objet de n'importe quel type à la méthode. Cependant, si le transtypage n'est pas valide - si un objet du mauvais type est passé en argument - une exception est générée lors de l'exécution. Ce n'est pas aussi bien qu'un contrôle lors de la compilation, mais l'approche reste robuste. Notez qu'aucun transtypage n'est nécessaire lors de l'utilisation de cette méthode :
t t t
MouseTrap.caughtYa(mice.get(i)); t
MouseTrap.caughtYa(mice.get(i));
t t t
no cast is necessary.
t
t t t

Making a type-conscious ArrayList

t

Créer une ArrayList consciente du type

t t t
You might not want to give up on this issue just yet. A more ironclad solution is to create a new class using the ArrayList, such that it will accept only your type and produce only your type:
t Pas question toutefois de s'arrêter en si bon chemin. Une solution encore plus robuste consiste à créer une nouvelle classe utilisant une ArrayList, n'acceptant et ne produisant que des objets du type voulu :
t t t
//: c09:MouseList.java // A type-conscious ArrayList. import java.util.*; public class MouseList { private ArrayList list = new ArrayList(); public void add(Mouse m) { list.add(m); } public Mouse get(int index) { return (Mouse)list.get(index); } public int size() { return list.size(); } } ///:~ t
//: c09:MouseList.java
// Une ArrayList consciente du type.
import java.util.*;

public class MouseList {
  private ArrayList list = new ArrayList();
  public void add(Mouse m) {
    list.add(m);
  }
  public Mouse get(int index) {
    return (Mouse)list.get(index);
  }
  public int size() { return list.size(); }
} ///:~
t t t
Here’s a test for the new container:
t Voici un test pour le nouveau conteneur :
t t t
//: c09:MouseListTest.java public class MouseListTest { public static void main(String[] args) { MouseList mice = new MouseList(); for(int i = 0; i < 3; i++) mice.add(new Mouse(i)); for(int i = 0; i < mice.size(); i++) MouseTrap.caughtYa(mice.get(i)); } } ///:~ t
//: c09:MouseListTest.java
public class MouseListTest {
  public static void main(String[] args) {
    MouseList mice = new MouseList();
    for(int i = 0; i < 3; i++)
      mice.add(new Mouse(i));
    for(int i = 0; i < mice.size(); i++)
      MouseTrap.caughtYa(mice.get(i));
  }
} ///:~
t t t
This is similar to the previous example, except that the new MouseList class has a private member of type ArrayList, and methods just like ArrayList. However, it doesn’t accept and produce generic Objects, only Mouse objects.
t Cet exemple est similaire au précédent, sauf que la nouvelle classe MouseList dispose d'un membre private de type ArrayList, et de méthodes identiques à celles fournies par ArrayList. Cependant, ces méthodes n'acceptent et ne produisent pas des Objects génériques, mais seulement des objets Mouse.
t t t
Note that if MouseList had instead been inherited from ArrayList, the add(Mouse) method would simply overload the existing add(Object) and there would still be no restriction on what type of objects could be added. Thus, the MouseList becomes a surrogate to the ArrayList, performing some activities before passing on the responsibility (see Thinking in Patterns with Java, downloadable at www.BruceEckel.com).
t Notez que si MouseList avait été dérivée de ArrayList, la méthode add(Mouse) aurait simplement surchargé la méthode existante add(Object) et aucune restriction sur le type d'objets acceptés n'aurait donc été ajoutée. La MouseList est donc un substitut à l'ArrayList, réalisant certaines opérations avant de déléguer la responsabilité (cf. Thinking in Patterns with Java, téléchargeable sur www.BruceEckel.com).
t t t
Because a MouseList will accept only a Mouse, if you say:
t Du fait qu'une MouseList n'accepte qu'une Mouse, l'instruction suivante :
t t t
mice.add(new Pigeon()); t
mice.add(new Pigeon());
t t t
you will get an error message at compile-time. This approach, while more tedious from a coding standpoint, will tell you immediately if you’re using a type improperly.
t provoque un message d'erreur durant la phase de compilation. Cette approche, bien que plus fastidieuse du point de vue du code, signalera immédiatement si on utilise un type de façon incorrecte.
t t t
Note that no cast is necessary when using get( )—it’s always a Mouse.
t Notez aussi qu'aucun transtypage n'est nécessaire lors d'un appel à get() - elle renvoie toujours une Mouse.
t t t

Parameterized types

t

Types paramétrés

t t t
This kind of problem isn’t isolated—there are numerous cases in which you need to create new types based on other types, and in which it is useful to have specific type information at compile-time. This is the concept of a parameterized type. In C++, this is directly supported by the language with templates. It is likely that a future version of Java will support some variation of parameterized types; the current front-runner automatically creates classes similar to MouseList.
t Ce type de problème n'est pas isolé - nombreux sont les cas dans lesquels on a besoin de créer de nouveaux types basés sur d'autres types, et dans lesquels il serait bon de récupérer des informations de type lors de la phase de compilation. C'est le concept des types paramétrés. En C++, ceci est directement supporté par le langage via les templates. Les futures versions de Java supporteront probablement une implémentation des types paramétrés ; actuellement il faut se contenter de créer des classes similaires à MouseList.
t t t

Iterators

t

Itérateurs

t t t
In any container class, you must have a way to put things in and a way to get things out. After all, that’s the primary job of a container—to hold things. In the ArrayList, add( ) is the way that you insert objects, and get( ) is one way to get things out. ArrayList is quite flexible—you can select anything at any time, and select multiple elements at once using different indexes.
t Chaque classe conteneur fournit des méthodes pour stocker des objets et pour les extraire - après tout, le but d'un conteneur est de stocker des choses. Dans ArrayList, on insère des objets via la méthode add(), et get() est l'un des moyens de récupérer ces objets. ArrayList est relativement souple - il est possible de sélectionner n'importe quel élément à n'importe quel moment, ou de sélectionner plusieurs éléments en même temps en utilisant différents index.
t t t
If you want to start thinking at a higher level, there’s a drawback: you need to know the exact type of the container in order to use it. This might not seem bad at first, but what if you start out using an ArrayList, and later on in your program you discover that because of the way you are using the container it would be much more efficient to use a LinkedList instead? Or suppose you’d like to write a piece of generic code that doesn’t know or care what type of container it’s working with, so that it could be used on different types of containers without rewriting that code?
t Si on se place à un niveau d'abstraction supérieur, on s'aperçoit d'un inconvénient : on a besoin de connaître le type exact du conteneur afin de l'utiliser. Ceci peut sembler bénin à première vue, mais qu'en est-il si on commence à programmer en utilisant une ArrayList, et qu'on se rende compte par la suite qu'il serait plus efficace d'utiliser une LinkedList à la place ? Ou alors si on veut écrire une portion de code générique qui ne connait pas le type de conteneur avec lequel elle travaille, afin de pouvoir être utilisé avec différents types de conteneurs sans avoir à réécrire ce code ?
t t t
The concept of an iterator can be used to achieve this abstraction. An iterator is an object whose job is to move through a sequence of objects and select each object in that sequence without the client programmer knowing or caring about the underlying structure of that sequence. In addition, an iterator is usually what’s called a “light-weight” object: one that’s cheap to create. For that reason, you’ll often find seemingly strange constraints for iterators; for example, some iterators can move in only one direction.
t Le concept d'itérateur peut être utilisé pour réaliser cette abstraction. Un itérateur est un objet dont le travail est de se déplacer dans une séquence d'objets et de sélectionner chaque objet de cette séquence sans que le programmeur client n'ait à se soucier de la structure sous-jacente de cette séquence. De plus, un itérateur est généralement ce qu'il est convenu d'appeler un objet « léger » : un objet bon marché à construire. Pour cette raison, vous trouverez souvent des contraintes étranges sur les itérateurs ; par exemple, certains itérateurs ne peuvent se déplacer que dans un sens.
t t t
The Java Iterator is an example of an iterator with these kinds of constraints. There’s not much you can do with one except:
t L'Iterator Java est l'exemple type d'un itérateur avec ce genre de contraintes. On ne peut faire grand-chose avec mis à part :
t t t
  1. Ask a container to hand you an Iterator using a method called iterator( ). This Iterator will be ready to return the first element in the sequence on your first call to its next( ) method.
  2. Get the next object in the sequence with next( ).
  3. See if there are any more objects in the sequence with hasNext( ).
  4. Remove the last element returned by the iterator with remove( ).
t
  1. Demander à un conteneur de renvoyer un Iterator en utilisant une méthode appelée iterator(). Cet Iterator sera prêt à renvoyer le premier élément dans la séquence au premier appel à sa méthode next().
  2. Récupérer l'objet suivant dans la séquence grâce à sa méthode next().
  3. Vérifier s'il reste encore d'autres objets dans la séquence via la méthode hasNext().
  4. Enlever le dernier élément renvoyé par l'itérateur avec la méthode remove().
t t t
That’s all. It’s a simple implementation of an iterator, but still powerful (and there’s a more sophisticated ListIterator for Lists). To see how it works, let’s revisit the CatsAndDogs.java program from earlier in this chapter. In the original version, the method get( ) was used to select each element, but in the following modified version an Iterator is used:
t Et c'est tout. C'est une implémentation simple d'un itérateur, mais néanmoins puissante (et il existe un ListIterator plus sophistiqué pour les Lists). Pour le voir en action, revisitons le programme CatsAndDogs.java rencontré précédemment dans ce chapitre. Dans sa version originale, la méthode get() était utilisée pour sélectionner chaque élément, mais la version modifiée suivante se sert d'un Iterator :
t t t
//: c09:CatsAndDogs2.java // Simple container with Iterator. import java.util.*; public class CatsAndDogs2 { public static void main(String[] args) { ArrayList cats = new ArrayList(); for(int i = 0; i < 7; i++) cats.add(new Cat(i)); Iterator e = cats.iterator(); while(e.hasNext()) ((Cat)e.next()).print(); } } ///:~ t
//: c09:CatsAndDogs2.java
// Conteneur simple utilisant un Iterator.
import java.util.*;

public class CatsAndDogs2 {
  public static void main(String[] args) {
    ArrayList cats = new ArrayList();
    for(int i = 0; i < 7; i++)
      cats.add(new Cat(i));
    Iterator e = cats.iterator();
    while(e.hasNext())
      ((Cat)e.next()).print();
  }
} ///:~
t t t
You can see that the last few lines now use an Iterator to step through the sequence instead of a for loop. With the Iterator, you don’t need to worry about the number of elements in the container. That’s taken care of for you by hasNext( ) and next( ).
t Les dernières lignes utilisent maintenant un Iterator pour se déplacer dans la séquence à la place d'une boucle for. Avec l'Iterator, on n'a pas besoin de se soucier du nombre d'éléments dans le conteneur. Cela est géré via les méthodes hasNext() et next().
t t t
As another example, consider the creation of a general-purpose printing method:
t Comme autre exemple, considérons maintenant la création d'une méthode générique d'impression :
t t t
//: c09:HamsterMaze.java // Using an Iterator. import java.util.*; class Hamster { private int hamsterNumber; Hamster(int i) { hamsterNumber = i; } public String toString() { return "This is Hamster #" + hamsterNumber; } } class Printer { static void printAll(Iterator e) { while(e.hasNext()) System.out.println(e.next()); } } public class HamsterMaze { public static void main(String[] args) { ArrayList v = new ArrayList(); for(int i = 0; i < 3; i++) v.add(new Hamster(i)); Printer.printAll(v.iterator()); } } ///:~ t
//: c09:HamsterMaze.java
// Utilisation d'un Iterator.
import java.util.*;

class Hamster {
  private int hamsterNumber;
  Hamster(int i) { hamsterNumber = i; }
  public String toString() {
    return "This is Hamster #" + hamsterNumber;
  }
}

class Printer {
  static void printAll(Iterator e) {
    while(e.hasNext())
      System.out.println(e.next());
  }
}

public class HamsterMaze {
  public static void main(String[] args) {
    ArrayList v = new ArrayList();
    for(int i = 0; i < 3; i++)
      v.add(new Hamster(i));
    Printer.printAll(v.iterator());
  }
} ///:~
t t t
Look closely at printAll( ). Note that there’s no information about the type of sequence. All you have is an Iterator, and that’s all you need to know about the sequence: that you can get the next object, and that you can know when you’re at the end. This idea of taking a container of objects and passing through it to perform an operation on each one is powerful, and will be seen throughout this book.
t Examinez attentivement la méthode printAll() et notez qu'elle ne dispose d'aucune information sur le type de séquence. Tout ce dont elle dispose est un Iterator, et c'est la seule chose dont elle a besoin pour utiliser la séquence : elle peut récupérer l'objet suivant, et savoir si elle se trouve à la fin de la séquence. Cette idée de prendre un conteneur d'objets et de le parcourir pour réaliser une opération sur chaque élément est un concept puissant, et on le retrouvera tout au long de ce livre.
t t t
The example is even more generic, since it implicitly uses the Object.toString( ) method. The println( ) method is overloaded for all the primitive types as well as Object; in each case a String is automatically produced by calling the appropriate toString( ) method.
t Cet exemple est même encore plus générique, puisqu'il utilise implicitement la méthode Object.toString(). La méthode println() est surchargée pour tous les types scalaires ainsi que dans Object ; dans chaque cas une String est automatiquement produite en appelant la méthode toString() appropriée.
t t t
Although it’s unnecessary, you can be more explicit using a cast, which has the effect of calling toString( ):
t Bien que cela ne soit pas nécessaire, on pourrait être plus explicite en transtypant le résultat, ce qui aurait pour effet d'appeler toString() :
t t t
System.out.println((String)e.next()); t
System.out.println((String)e.next());
t t t
In general, however, you’ll want to do something more than call Object methods, so you’ll run up against the type-casting issue again. You must assume you’ve gotten an Iterator to a sequence of the particular type you’re interested in, and cast the resulting objects to that type (getting a run-time exception if you’re wrong).
t En général, cependant, on voudra certainement aller au-delà de l'appel des méthodes de la classe Object, et on se heurte de nouveau au problème du transtypage. Il faut donc assumer qu'on a récupéré un Iterator sur une séquence contenant des objets du type particulier qui nous intéresse, et transtyper les objets dans ce type (et recevoir une exception à l'exécution si on se trompe).
t t t

Unintended recursion

t

Récursion indésirable

t t t
Because (like every other class), the Java standard containers are inherited from Object, they contain a toString( ) method. This has been overridden so that they can produce a String representation of themselves, including the objects they hold. Inside ArrayList, for example, the toString( ) steps through the elements of the ArrayList and calls toString( ) for each one. Suppose you’d like to print the address of your class. It seems to make sense to simply refer to this (in particular, C++ programmers are prone to this approach):
t Comme les conteneurs standard Java héritent de la classe Object (comme toutes les autres classes), ils contiennent une méthode toString(). Celle-ci a été redéfinie afin de produire une représentation String d'eux-mêmes, incluant les objets qu'ils contiennent. A l'intérieur d'ArrayList, la méthode toString() parcourt les éléments de l'ArrayList et appelle toString() pour chacun d'eux. Supposons qu'on veuille afficher l'adresse de l'instance. Il semble raisonnable de se référer à this (en particulier pour les programmeurs C++ qui sont habitués à cette approche) :
t t t
//: c09:InfiniteRecursion.java // Accidental recursion. import java.util.*; public class InfiniteRecursion { public String toString() { return " InfiniteRecursion address: " + this + "\n"; } public static void main(String[] args) { ArrayList v = new ArrayList(); for(int i = 0; i < 10; i++) v.add(new InfiniteRecursion()); System.out.println(v); } } ///:~ t
//: c09:InfiniteRecursion.java
// Récursion accidentelle.
import java.util.*;

public class InfiniteRecursion {
  public String toString() {
    return " InfiniteRecursion address: "
      + this + "\n";
  }
  public static void main(String[] args) {
    ArrayList v = new ArrayList();
    for(int i = 0; i < 10; i++)
      v.add(new InfiniteRecursion());
    System.out.println(v);
  }
} ///:~
t t t
If you simply create an InfiniteRecursion object and then print it, you’ll get an endless sequence of exceptions. This is also true if you place the InfiniteRecursion objects in an ArrayList and print that ArrayList as shown here. What’s happening is automatic type conversion for Strings. When you say:
t Si on crée un objet InfiniteRecursion et qu'on veut l'afficher, on se retrouve avec une séquence infinie d'exceptions. C'est également vrai si on place des objets InfiniteRecursion dans une ArrayList et qu'on imprime cette ArrayList comme c'est le cas ici. Ceci est du à la conversion automatique de type sur les Strings. Quand on écrit :
t t t
"InfiniteRecursion address: " + this t
"InfiniteRecursion address: " + this
t t t
The compiler sees a String followed by a ‘+’ and something that’s not a String, so it tries to convert this to a String. It does this conversion by calling toString( ), which produces a recursive call.
t Le compilateur voit une String suivie par un « + » et quelque chose qui n'est pas une String, il essaie donc de convertir this en String. Il réalise cette conversion en appelant toString(), ce qui produit un appel récursif.
t t t
If you really do want to print the address of the object in this case, the solution is to call the Object toString( ) method, which does just that. So instead of saying this, you’d say super.toString( ). (This only works if you're directly inheriting from Object, or if none of your parent classes have overridden the toString( ) method.)
t Si on veut réellement imprimer l'adresse de l'objet dans ce cas, la solution est d'appeler la méthode Object.toString(), qui réalise exactement ceci. Il faut donc utiliser super.toString() à la place de this (ceci ne fonctionnera que si on hérite directement de la classe Object, ou si aucune classe parent n'a redéfini la méthode toString()).
t t t

Container taxonomy

t

Classification des conteneurs

t t t
Collections and Maps may be implemented in different ways, according to your programming needs. It’s helpful to look at a diagram of the Java 2 containers:
t Les Collections et les Maps peuvent être implémentés de différentes manières, à vous de choisir la bonne selon vos besoins. Le diagramme suivant peut aider à s'y retrouver parmi les conteneurs Java 2 :    
t t t

t Image
t t t
This diagram can be a bit overwhelming at first, but you’ll see that there are really only three container components: Map, List, and Set, and only two or three implementations of each one (with, typically, a preferred version). When you see this, the containers are not so daunting.
t Ce diagramme peut sembler un peu surchargé à première vue, mais il n'y a en fait que trois types conteneurs de base : les Maps, les Lists et les Sets, chacun d'entre eux ne proposant que deux ou trois implémentations (avec typiquement une version préférée). Quand on se ramène à cette observation, les conteneurs ne sont plus aussi intimidants.
t t t
The dotted boxes represent interfaces, the dashed boxes represent abstract classes, and the solid boxes are regular (concrete) classes. The dotted-line arrows indicate that a particular class is implementing an interface (or in the case of an abstract class, partially implementing that interface). The solid arrows show that a class can produce objects of the class the arrow is pointing to. For example, any Collection can produce an Iterator, while a List can produce a ListIterator (as well as an ordinary Iterator, since List is inherited from Collection).
t Les boîtes en pointillé représentent les interfaces, les boîtes en tirets représentent des classes abstract, et les boîtes pleines sont des classes normales (concrètes). Les lignes pointillées indiquent qu'une classe particulière implémente une interface (ou dans le cas d'une classe abstract, implémente partiellement cette interface). Une flèche pleine indique qu'une classe peut produire des objets de la classe sur laquelle la flèche pointe. Par exemple, une Collection peut produire un Iterator, tandis qu'une List peut produire un ListIterator (ainsi qu'un Iterator ordinaire, puisque List est dérivée de Collection).
t t t
The interfaces that are concerned with holding objects are Collection, List, Set, and Map. Ideally, you’ll write most of your code to talk to these interfaces, and the only place where you’ll specify the precise type you’re using is at the point of creation. So you can create a List like this:
t Les interfaces concernées par le stockage des objets sont Collection, List, Set et Map. Idéalement, la majorité du code qu'on écrit sera destinée à ces interfaces, et le seul endroit où on spécifiera le type précis utilisé est lors de la création. On pourra donc créer une List de cette manière :
t t t
List x = new LinkedList(); t
List x = new LinkedList();
t t t
t t t
t t
\\\
///
t t t
t
     
Sommaire Le site de Bruce Eckel