Usine générique avec des classes d’implémentation inconnues

Supposons deux interfaces:

public interface FruitHandler { setFruit(T fruit); T getFruit(); } public interface Fruit { } 

Maintenant, je veux une fabrique pour créer FruitHandlers (par exemple AppleHander , OrangeHandler , …), mais FruitHandlerFactory ne sait pas ce FruitHandlerFactory faut savoir sur les classes d’implémentation des deux interfaces (comme dans la fabrique statique générique paramétrée en Java ). Le FruitHandlerFactory devrait fonctionner de cette façon (où OrangeHandler implémente FruitHandler et Orange implémente Fruit ):

 FruitHandlerFactory fhf = new FruitHandlerFactory(); OrangeHandler fh = fhf.create(); Orange orange = (Orange)fh.getFruit(); 

Cela devrait être l’usine:

 public class FruitHandlerFactory { public FruitHandler create() { FruitHandler fh = new A(); //<--- ERROR fh.setFruit(new B()); return fh; } } 

Où j’obtiens cette erreur:

 The type A is not generic; it cannot be parameterized with arguments  

BTW: Est-il possible de rendre la méthode create() statique?

Comme les génériques en Java sont implémentés à l’aide de l’effacement, les informations de type de FruitHandlerFactory ne seront pas disponibles au moment de l’exécution, ce qui signifie que vous ne pouvez pas instancier A (ou B ) de cette manière.

Vous pouvez cependant passer un object Class du type correct pour contourner ce problème:

 public class FruitHandlerFactory, F extends Fruit> { final Class handlerClass; final Class fruitClass; public FruitHandlerFactory(final Class handlerClass, final Class fruitClass) { this.handlerClass = handlerClass; this.fruitClass = fruitClass; } public H create() throws InstantiationException, IllegalAccessException { H handler = handlerClass.newInstance(); handler.setFruit(fruitClass.newInstance()); return handler; } } 

Un inconvénient mineur est que vous devrez écrire les noms de type trois fois (1) si vous souhaitez instancier une FruitHandlerFactory :

 FruitHandlerFactory fhf = new FruitHandlerFactory(OrangeHandler.class, Orange.class); 

Vous pouvez quelque peu réduire cela en produisant une méthode createFactory() static sur votre FruitHandlerFactory :

 static , F extends Fruit> FruitHandlerFactory createFactory( final Class handlerClass, final Class fruitClass) { return new FruitHandlerFactory(handlerClass, fruitClass); } 

et l’utiliser comme ça:

 FruitHandlerFactory fhf = FruitHandlerFactory.createFactory(OrangeHandler.class, Orange.class); 

De cette question :

Peut-être essayer cela?

 public class FruitHandlerFactory, B extends Fruit>