Niveau avancé

Résumé syntaxique avancé #

Générique #

Il s’agit du dernier type de polymorphisme: le polymorphisme paramétrique.

Terminologie:

  • Pour un type G<E>
    • G est un type générique.
    • E est un type paramétrique ou un paramètre du type G. Un type générique peut avoir plusieurs paramètres.
    • Une fois le ou les paramètres renseignés, un type générique devient un type concret:
      • G<Integer> est un type concret
    • Il est possible de borner un paramètre: G<E extends X> indique que le paramètre doit au moins éteindre d’un type X

Effacement #

Lors de la compilation, un paramètre est remplacé par un Object (si non borné).

1
2
3
4
5
6
7
8
9
public class Box<T> {
  private T t;
  public Box(T t) { this.t = t; }
  public void set(T t) { this.t = t; }
  public T get() { return this.t; }
}
// Utilistion quelconque
Box<Integer> bi = new Box<>(10);
int i = bi.get(); 

devient:

1
2
3
4
5
6
7
8
9
public class Box {
  private Object t;
  public Box(Object t) { this.t = t; }
  public void set(Object t) { this.t = t; }
  public Object get() { return this.t; }
}
// Utilistion quelconque
Box bi = new Box(10);
int i = (Integer)bi.get();

Limitations #

  • Le type du paramètre est “effacé”. A l’exécution, il est impossible de le connaître, ce qui apporte des limitations (cf. théorie).
  • Le “raw type” est un type générique dont le paramètre ou les chevrons ne sont pas renseignés:
    • Box b = new Box();
    • Box<Integer> b = new Box();
    • Ces deux exemples léveront un avertissement à la compilation. Ce sera l’équivalent d’un Box<Object>
  • Ne pas oublier les chevrons lors de chaque appel. A droite de l’égalité, il devient facultatif:
    • Box<Integer> b = new Box<>();
    • Box<Integer> b = new Box<Integer>();

Paramètre borné #

Il est possible de borner un paramètre:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
interface HasSomething {
  boolean hasSomething();
}
public class Box<T extends HasSomething> {
  private T t;
  void test( {
    if (this.t.hasSomething()) { // il dès lors possible d'appeler les membres de cette borne
      ...
    }
  })
}

Dans ce cas, HasSomething serait substitué à T lors de l’effacement en lieu est place de Object.

Un paramètre peut-être borné par plusieurs interfaces et par une classe au plus:

<T extends I1 & I2 & I3> // T doit respecter plusieurs interfaces
<T extends C & I1 & I2> // T doit être une classe C ou hériter de C 
                        // et respecter les interfaces I1 et I2











comments powered by Disqus