Maybe what you want is just this:
T3 newInstance = T3.class.getConstructor().newInstance();
In that code, T3.class
is an object of the type Class<T3>
. From it, you can create instances. This code assumes that T3
has a constructor without parameters.
Let’s assume that T4
, on the other hand, has a constructor with a type parameter String
. In that case:
T4 newInstance = T4.class.getConstructor(String.class).newInstance("Teste");
The parameters of getConstructor(...)
correspond to the types of parameters of the desired constructor, while those of the newInstance(...)
are the values themselves.
You can use the Class.forName(String)
to get the class by name. But this will give a code like this:
Class<?> clazz = Class.forName("br.com.macadu.aprendizado.testando.T3");
Object instance = clazz.getConstructor().newInstance();
This is particularly useful for you to instantiate classes just by name without knowing exactly what class it is, such as when you have a user-given class name, read from a file, or something like that. But the downside is that like in these cases, the instantiated class can be anything, the only common type you have is Object
.
You could even do that:
Class<?> clazz = Class.forName("br.com.macadu.aprendizado.testando.T3");
T3 instance = (T3) clazz.getConstructor().newInstance();
But, that doesn’t make much sense, after all she doesn’t have much advantage over the T3.class.getConstructor().newInstance();
.
When you want to instantiate subclasses or implementers of an interface, it gets more interesting:
String implementacao = "com.example.ClasseQueImplementaMinhaInterface";
Class<? extends MinhaInterface> clazz = Class.forName(implementacao)
.asSubclass(MinhaInterface.class);
MinhaInterface instance = clazz.getConstructor().newInstance();
Use the method newInstance()
class Class
it might seem like it would be easier, but he was branded as deprecated since Java 9 due to the fact that this method does not behave well in case the constructor throws an exception. In addition, it only works for public builders without parameters.
Finally, if the constructor you want to access is not public, use getDeclaredConstructor(...)
instead of getConstructor(...)
. Also use the setAccessible(true)
to ensure access permission even if the class is not public and is in some other package.
String implementacao = "com.example.MaisOutraClasseQueImplementaMinhaInterface";
Class<? extends MinhaInterface> clazz = Class.forName(implementacao)
.asSubclass(MinhaInterface.class);
Constructor<? extends MinhaInterface> ctor = clazz.getDeclaredConstructor(String.class);
ctor.setAccessible(true);
MinhaInterface instance = ctor.newInstance("Teste");
I don’t understand what you mean by "caching for the type that he perceives". You already have the object
clazz
, and it represents the type. In addition, the methodClass.newInstance()
was considered deprecated in Java 9. Useclazz.getConstructor().newInstance()
in place.– Victor Stafusa
Because you do
newInstance.getClass()
instead of usingclazz
?– Victor Stafusa