Pourquoi le nouveau T () n'est pas possible en Java

Les gens pensent parfois que le «nouveau T ()» serait possible si les génériques étaient réifiés. Ce n'est pas vrai. Considérer:

classe Foo {

T f = nouveau T ();

}

Avec l'effacement, vous implémentez 'new T ()' comme 'new Object ()', puisque Object est la borne de T. Avec la réification, vous instanciez un objet dont la classe est la liaison dynamique pour T dans 'this'. Dans tous les cas, vous devez exécuter un constructeur no-args.

Mais Foo n'exige pas qu'un type lié à T (alias un témoin de T) ait un constructeur no-args. 'new Foo ()' est parfaitement légal, mais Integer n'a pas de constructeur no-args, alors comment l'expression d'initialisation d'instance est-elle censée appeler 'new T ()'? Il peut difficilement constituer une valeur par défaut à transmettre au constructeur d'Integer.

'new T ()' n'est fondamentalement pas possible dans le contexte de bornes de type nominal . (Ou, si vous préférez, dans un contexte de compilation séparée, puisqu'une compilation globale pourrait calculer que 'new T ()' est sain pour toutes les instanciations observées de Foo.) C # 2.0 a introduit une contrainte de type structurel appelée la contrainte new () pour autoriser «nouveau T ()». Cependant, ils avaient déjà besoin de règles intéressantes sur les types pouvant être témoins d'un paramètre de type, et dans ce contexte, la "contrainte publique sans paramètre" est simple. Les «concepts» C ++ vont plus loin en permettant une description structurelle des types capables d'assister à un paramètre de type.

Java n'obtiendra pas de limites de type structurel de sitôt. Les bornes de type nominal de la forme C&I (un type d'intersection) sont assez compliquées. Par conséquent, ni l'effacement ni la réification ne peuvent à eux seuls prendre en charge le «nouveau T ()».

Cette histoire, "Pourquoi le nouveau T () n'est pas possible en Java" a été initialement publiée par JavaWorld.