2008-11-18 24 views

Odpowiedz

57

Po wymazaniu typu wszystko, co wiadomo na temat T, jest podklasą Object. Musisz określić fabrykę, aby utworzyć instancje T.

Jedno podejście przydałoby się Supplier<T>:

class MyClass<T> { 

    private final Supplier<? extends T> ctor; 

    private T field; 

    MyClass(Supplier<? extends T> ctor) { 
    this.ctor = Objects.requireNonNull(ctor); 
    } 

    public void myMethod() { 
    field = ctor.get(); 
    } 

} 

Wykorzystanie może wyglądać następująco:

MyClass<StringBuilder> it = new MyClass<>(StringBuilder::new); 

Alternatywnie, można podać Class<T> obiekt, a następnie użyć refleksji.

class MyClass<T> { 

    private final Constructor<? extends T> ctor; 

    private T field; 

    MyClass(Class<? extends T> impl) throws NoSuchMethodException { 
    this.ctor = impl.getConstructor(); 
    } 

    public void myMethod() throws Exception { 
    field = ctor.newInstance(); 
    } 

} 
+0

Co Pakiet 'Supplier' znajduje się w? 'MyClass (klasa impl)' musi zadeklarować 'wyrzuca NoSuchMethodException' do kompilacji. Twoja odpowiedź nie jest niestety przyjazna dla początkującego języka Java. – user927387

+0

@ user927387 'java.util.function.Supplier' – erickson

10

może to być więcej niż wagi ciężkiej co szukasz, ale będzie również działać. Zauważ, że jeśli podejmiesz takie podejście, bardziej sensownym byłoby wstrzyknięcie fabryki do MyClass, gdy zostanie ona skonstruowana, zamiast przekazywania jej do metody za każdym razem, gdy zostanie wywołana.

interface MyFactory<T> 
{ 
    T newObject(); 
} 

class MyClass<T> 
{ 
    T field; 
    public void myMethod(MyFactory<T> factory) 
    { 
     field = factory.newObject() 
    } 
} 
+1

Dobre, nieodblaskowe podejście; odbicie nie zawsze jest opcją. myMethod powinien być w stanie zaakceptować MyFactory , prawda? – erickson

+0

Dobra rozmowa - będziesz chciał umieścić ograniczony znak wieloznaczny w fabryce, aby umożliwić tworzenie obiektów typu T i podklas T w myMethod(). –

11

Innym nieodblaskowym podejściem jest użycie hybrydowego wzoru Builder/Abstract Factory.

W Effective Java, Joshua Bloch podchodzi wzoru Builder w szczegółach, i popiera ogólny interfejs Builder:

public interface Builder<T> { 
    public T build(); 
} 

betonowe budowniczowie mogą implementować ten interfejs, a zajęcia na zewnątrz można użyć betonu budowniczy, aby skonfigurować Builder zgodnie z wymaganiami. Budowniczy może zostać przekazany do MyClass jako Builder<T>.

Używając tego wzorca, można uzyskać nowe instancje T, nawet jeśli T ma parametry konstruktora lub wymaga dodatkowej konfiguracji. Oczywiście będziesz potrzebował jakiegoś sposobu przekazania Buildera do MyClass. Jeśli nie możesz przekazać niczego do MyClass, to Builder i Abstract Factory są niedostępne.

1

Klasa classOfT

 try { 
      t = classOfT.newInstance();//new T(); NOTE: type parameter T cannot be instantiated directly 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
Powiązane problemy