Mam następującą klasę szablonów:
class MyClass<T>
{
T field;
public void myMethod()
{
field = new T(); // gives compiler error
}
}
Jak utworzyć nowe wystąpienie T w mojej klasie?
java
generics
reflection
Rtęć
źródło
źródło
Supplier
znajduje? `MyClass (Class <? Extends T> impl)` musi zadeklarować `throws NoSuchMethodException` do skompilowania. Twoja odpowiedź niestety nie jest przyjazna dla początkujących użytkowników języka Java.java.util.function.Supplier
Innym nierefleksyjnym podejściem jest użycie hybrydowego wzorca Builder / Abstract Factory.
W Effective Java Joshua Bloch omawia szczegółowo wzorzec Builder i opowiada się za ogólnym interfejsem Builder:
public interface Builder<T> { public T build(); }
Konstruktorzy betonu mogą implementować ten interfejs, a klasy zewnętrzne mogą używać konstruktora betonu do konfigurowania Konstruktora zgodnie z wymaganiami. Konstruktora można przekazać do MyClass jako plik
Builder<T>
.Korzystając z tego wzorca, można uzyskać nowe wystąpienia programu
T
, nawet jeśliT
ma parametry konstruktora lub wymaga dodatkowej konfiguracji. Oczywiście będziesz potrzebować jakiegoś sposobu, aby przekazać Konstruktora do MyClass. Jeśli nie możesz niczego przekazać do MyClass, to Builder i Abstract Factory są niedostępne.źródło
To może być cięższe niż to, czego szukasz, ale też zadziała. Zauważ, że jeśli zastosujesz to podejście, bardziej sensowne byłoby wstrzyknięcie fabryki do MyClass podczas jej tworzenia, zamiast przekazywania jej do metody za każdym razem, gdy jest ona wywoływana.
interface MyFactory<T> { T newObject(); } class MyClass<T> { T field; public void myMethod(MyFactory<T> factory) { field = factory.newObject() } }
źródło
Jeśli chcesz dołączyć do podklasy, możesz również uniknąć wymazywania, sprawdź http://www.artima.com/weblogs/viewpost.jsp?thread=208860
źródło
Klasa classOfT
try { t = classOfT.newInstance();//new T(); NOTE: type parameter T cannot be instantiated directly } catch (Exception e) { e.printStackTrace(); }
źródło