Eu tenho uma classe de modelo como segue:
class MyClass<T>
{
T field;
public void myMethod()
{
field = new T(); // gives compiler error
}
}
Como faço para criar uma nova instância de T em minha classe?
java
generics
reflection
Mercurário
fonte
fonte
Supplier
está localizado? `MyClass (Class <? Extends T> impl)` deve declarar `throws NoSuchMethodException` para ser compilado. Sua resposta infelizmente não é amigável para iniciantes em Java.java.util.function.Supplier
Outra abordagem não reflexiva é usar um padrão híbrido Builder / Abstract Factory.
Em Effective Java, Joshua Bloch examina o padrão Builder em detalhes e defende uma interface Builder genérica:
public interface Builder<T> { public T build(); }
Construtores concretos podem implementar esta interface e classes externas podem usar o construtor concreto para configurar o Construtor conforme necessário. O construtor pode ser passado para MyClass como um
Builder<T>
.Usando esse padrão, você pode obter novas instâncias de
T
, mesmo queT
tenha parâmetros de construtor ou exija configuração adicional. Obviamente, você precisará de alguma forma de passar o Builder para MyClass. Se você não pode passar nada para MyClass, então Builder e Abstract Factory estão fora.fonte
Isso pode ser mais pesado do que o que você está procurando, mas também funcionará. Observe que, se você adotar essa abordagem, faria mais sentido injetar a fábrica em MyClass quando ela for construída, em vez de passá-la para seu método cada vez que for chamada.
interface MyFactory<T> { T newObject(); } class MyClass<T> { T field; public void myMethod(MyFactory<T> factory) { field = factory.newObject() } }
fonte
Se você deseja criar uma subclasse, também pode evitar o apagamento, consulte http://www.artima.com/weblogs/viewpost.jsp?thread=208860
fonte
Uma opção seria lançá-lo com Object
{field = (T) new Object();}
O campo será inicialmente do tipo Object, mas depois será convertido para o tipo T. Este é feio porque reduzir a conversão a zero é o que o objetivo deve ser para inicializações de objeto. Mas acho que isso vai funcionar.
fonte
Class classOfT
try { t = classOfT.newInstance();//new T(); NOTE: type parameter T cannot be instantiated directly } catch (Exception e) { e.printStackTrace(); }
fonte