Christophe Jacquet

C# : 1 – Java : 0

À l’occasion de quelques amusements en C# effectués en ce moment…

Il y a deux ans, je m’étais plaint des generics de Java. En effet, le paramétrage des types est effacé à la compilation, ce qui rend certaines opérations impossibles à faire. Par exemple la méthode toArray de l’interface List doit recevoir en paramètre un tableau du type paramètre, car celui-ci est oublié à la compilation. Mais hors de question de pouvoir écrire :

public static <T> T[] truc(T a) {
	List<T> liste = new ArrayList<T>();
	liste.add(a);
	return liste.toArray(new T[] {});
}

L’expression soulignée est incorrecte, parce que justement, à l’exécution la JVM ne connaît pas T… Problème insoluble.

Dans .Net, la CLR n’oublie pas le type des paramètres. Dans une méthode paramétrée par <T>, on peut donc parfaitement écrire une expression du type new T[] { ... }. Et la méthode ToArray n’a donc pas besoin qu’on lui fournisse un tableau du type paramètre. Le code ci-dessus, incorrect en Java, s’écrit de façon élégante en C# :

public static T[] truc<T>(T a)
{
	List<T> liste = new List<T>();
	liste.Add(a);
	return liste.ToArray();
}

Notons que pour ne rien simplifier, les concepteurs de Java et C# ont forcément trouvé le moyen de faire différer la syntaxe au niveau de la place du paramètre <T> dans la déclaration de fonction… Mais clairement, les generics me semblent avoir été traités à la légère en Java. Le système de l’erasure des informations de type, même s’il est suffisant pour assurer la type safety dans la plupart des cas, et même s’il permettait de garder la JVM inchangée, conduit à des solutions vraiment épouvantables (cast + @SuppressWarnings("unchecked")) dans des cas un peu complexes…

HTML5 valide ? © . ✍ Contact. Mentions légales.