Reflect caching java, how to do?

0

If I can instantiate a new object with reflection, how can I make caching for the type it belongs to? newInstance() returns a type Object but I need the primary object, which I can get the type by name.

But I want to deal with this in a different way.

Translating. I want to get through the class name to use the class normally.

Class<?> clazz = Class.forName("br.com.macadu.aprendizado.testando.T3");
Object newInstance = clazz.newInstance();
log.info(newInstance.getClass().toString());
for (Field field : newInstance.getClass().getFields()) {
    log.info(field.toString());
}

How did you come to doubt the question. What I want is to instantiate a class via reflection and return an object of the type that the object is. Not of type Object as some believed to be.

    
asked by anonymous 13.04.2018 / 14:20

2 answers

1

Maybe what you want is just that:

T3 newInstance = T3.class.getConstructor().newInstance();

In this code, T3.class is an object of type Class<T3> . From it, you can create instances. This code assumes that T3 has a constructor with no parameters.

Suppose that T4 , on the other hand, has a constructor with a parameter of type String . In this 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 newInstance(...) are the values themselves.

You can use 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 instantiating classes just by their 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 disadvantage is that because in these cases, the instantiated class can be anything, the only common type you have is Object .

You could even do this:

Class<?> clazz = Class.forName("br.com.macadu.aprendizado.testando.T3");
T3 instance = (T3) clazz.getConstructor().newInstance();

But, that does not make much sense, after all it does not have much advantage over T3.class.getConstructor().newInstance(); .

When you want to instantiate subclasses or implementors of an interface, this becomes more interesting:

String implementacao = "com.example.ClasseQueImplementaMinhaInterface";
Class<? extends MinhaInterface> clazz = Class.forName(implementacao)
        .asSubclass(MinhaInterface.class);
MinhaInterface instance = clazz.getConstructor().newInstance();

Use method newInstance() of class Class might seem like it would be easier, but it has been marked 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 constructors without parameters.

Finally, if the constructor you want to access is not public, use getDeclaredConstructor(...) instead of getConstructor(...) . Also use setAccessible(true) to grant 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");
    
18.04.2018 / 17:24
0

If I understand your question right, just do this:

Class<?> clazz = Class.forName("br.com.macadu.aprendizado.testando.T3");
log.info(clazz.toString());
for (Field field : clazz.getFields()) {
    log.info(field.toString());
}

You do not need to create an instance of the class if the only thing that interests you is the object Class .

In addition, the method newInstance() of class Class has been marked deprecated since Java 9 due to the fact that this method does not behave well in case the constructor throws an exception. So, instead:

Object newInstance = clazz.newInstance();

Use this:

Object newInstance = clazz.getDeclaredConstructor().newInstance();

Or if you prefer (and are sure that the constructor is public), use this:

Object newInstance = clazz.getConstructor().newInstance();
    
13.04.2018 / 15:46