Profession.java

import java.lang.ref.*;
import java.util.*;
import java.io.*;
public class Profession {
  private static MyWeakHashMap map = new MyWeakHashMap();
  private String nomProf;
  /** Constructeur privé pour éviter des créations d'instances. */
  private Profession(String nomProf) {
    this.nomProf = nomProf;
  }
  /** Permet d'afficher les métiers répertoriés à un instant donné. */
  public static void enum(PrintStream ps) {
    map.enum(ps);
  }
  /** Fabrique de métiers. Unique accès aux instances de l'extérieur. */
  public static Profession get(String s) {
    Profession r = map.get(s);  // On ne crée un métier que 
    if (r==null) {              // s'il n'est pas dans la table. 
      r = new Profession(s);
      map.put(s,r);
    }
    return r;
  }
  /** Donne la représentation (le nom) d'une profession. */
  public String toString() { return nomProf; }
  /** Appelée lorsque l'objet profession est finalisé. */
  protected void finalize() {
    System.out.println("L'objet représentant le métier " 
               + nomProf + " est finalisé !");
  }
  /**
   * Classe interne représentant une table d'association stockant
   * les instances de métiers avec des références faibles. Les clefs
   * sont  les noms des professions et les valeurs sont les références
   * faibles encapsulant l'accès aux instances de Profession.
   */
  private static class MyWeakHashMap {
    private HashMap map;
    /** Crée une instance de la table d'association. */
    private MyWeakHashMap() {
      map = new HashMap();
    }
    /**
     * Retourne l'instance de Profession référencée par la valeur
     * (référence faible) correspondant à clef dans la table.
     */
    private Profession get(String clef) {
      WeakReference wr = (WeakReference) map.get(clef);
      if (wr==null) return null; // Pas d'entrée correspondant à la clef
      if (wr.get()==null) {
        // La profession a disparu, mais l'entrée correspondante (la
        // réf.  faible) existe encore dans la table. Il faut la retirer!
        map.remove(clef);
        return null;
      }
      return (Profession) wr.get();
    }
    /**
     * Enregistre un métier dans la table. Cette méthode écraserait
     * sans vergogne une autre profession du même nom, mais vient
     * normalement juste après un get(), qui a vérifié que la
     * profession n'existait pas déjà.
     */
    private void put(String clef, Profession p) {
      WeakReference wr = new WeakReference(p);
      map.put(clef,wr);
    }
    /** Affiche toutes les valeurs contenues dans la table. */
    private void enum(PrintStream ps) {
      for (Iterator i=map.values().iterator(); i.hasNext(); ) {
    WeakReference wr = (WeakReference) i.next();
    if (wr.get()!=null) ps.print(wr.get() + " ");   
      }
      ps.println();
    }    
  }
}