I have an interface, LogParser, consisting of a single method parse(String x). I also have an ArrayList containing the names of multiple classes which all implement LogParser. Is it possible to loop through this list of class names and dynamically instantiate their respective classes and invoke parse(String x)?
The issue I've had is that the classes do not have zero-argument constructors, so I have run into InstantiationException a lot attempting to invoke the parse method through reflection.
Thanks!
If the implementation types don't have constructors, it will be very painful. The easiest way to do it is probably to use a dependency injection framework like Spring or Guice.
In Spring, you could just inject a List<LogParser>, and you would get all known implementations:
#Autowired
private List<LogParser> parsers;
Now of course you would have to define each of the LogParsers separately as Spring bean.
There is similar functionality in other frameworks as well.
You have to invoke some constructor to instantiate an object usefully. You use reflection to grab the Method for the constructor, and you instantiate with that. See Instantiate a class object with constructor that accepts a string parameter?. I didn't close as duplicate, since you have the additional question: Do you know that all your classes have a constructor with the same signature?
Related
This question already has an answer here:
How to dynamically create new class implementing some interface and instantiate it?
(1 answer)
Closed 2 years ago.
Is it possible to instantiate an interface just using java reflections?
I would like to have a factory method - producing interfaces, just by knowing its class.
public interface IReflection {
public default String say(){
return "test default";
}
}
public <T> T factoryProduce(Class<T> type){
// how to instantiate on factoryProduce(IReflection.class)
}
I am trying to simulate the following using reflections.
Because for the following I can not dynamically get the interface class
return new IReflection(){}
Using newInstance() failed, cause there is no constructor in the interface.
Constructor<?>[] con = IReflection.class.getDeclaredConstructors(); // empty
i = IReflection.class.newInstance(); // no constructor
i = IReflection.class.getDeclaredConstructor().newInstance(); // no constructor
Interfaces don't have constructors. They don't take part in the chain of constructors, implicitly or explicitly, calling super from the most derived class to java.lang.Object.
I suggest avoiding reflection, but if you absolutely have to for some reason, there is java.lang.reflect.Proxy. Unfortunately it does proxy default methods. There is this answer as a dirty hack around, or write a class loader to load a simple subtype.
An interface cannot be instantiated, not even with reflection (and not even when all its methods have a default implementation). You can only instantiate a class that implements the interface.
If you have a small set of interfaces that you need factoryProduce to support, you can simply create an implementing class for each of them, and create a map from interface type to implementing class. factoryProduce can then get the implementing class from this map, and instantiate it with reflection.
If you really need a completely dynamic solution, look at dynamic proxies, which are capable of creating a class at runtime that implements a given set of interfaces.
You cannot - of course - instantiate the interface, but you can instantiate the Class object defining the interface.
It is possible to compile the interface "on the fly" from a String containing the definition using javax.tools.JavaCompiler obtained from ToolProvider.getSystemJavaCompiler() and then use the java.lang.ClassLoader.defineClass() to define the class on the fly.
PS: I am using this technique in Obba, an Object Handler for Spreadsheets (there is an example that creates a class from a String containing the code during runtime).
I'm having a hard time understanding why javabeans are necessary and why they didn't just place the javabean features directly into the object class(root class) in java?
My understanding is you turn an object(instance) into a java bean and that way you get all the benefits like serializable and so on for all the objects in the bean. But if that is the case, why even have a separate bean class for this, why not just have built into the root object class?
Or am I not understand this?
You are not understanding it correctly.
There is no actual Java class or interface that is a bean. It is merely a pattern, a convention.
The bean convention is basically that a class will publicly expose some or all of its properties via public getXxx and setXxx methods, where XXX is the name of the property.
Beans generally should be serializable, but any class can be serializable, and does not need to follow the bean convention.
Besides that answer by Grey: even if there would be a Bean interface or method - not every fruit is an apple!
Meaning: there are zillions of classes that are just fine NOT being beans.
Beyond that: serialization as java does it was often found to be not that helpful. There are good reasons why we mostly serialize into JSON nowadays. In other words: we are pretty happy now that not all classes implement Serializeable by default; because Object being a Bean.
Just to talk about the no-argument constructor part of the bean pattern: A class does have a no argument constructor by default, but as soon as you create another constructor, that effectively removes it, as you probably know. But if you were forced to always have a no-argument constructor, this would be really annoying if you had a class which had a final field which is assigned by an argument in the constructor. You would then need to have some no argument constructor which either assigns everything to null, or throws an exception to tell other developers not to use the no argument so, which is just ugly.
I have query on bean instantiation in spring.
According to the Spring Reference document, in the section 'Instantiating beans", it is mentioned that
" container itself directly creates the bean by calling its constructor reflectively, somewhat equivalent to Java code using the new operator " .
This implies that Spring container uses reflection to create beans.How ever in few scenarios, container also uses static factory method on a class to create a bean. The only case I knew container use static factory method is "WHEN THE CONSTRUCTOR IS PRIVATE".
So my doubt is, since container uses Reflection to create objects, it should be able create objects of classes of even private constructor as well.Why should container rely on static factory method ?
Or are there any other uses of calling static factory method to create beans ?
Thanks in advance. If there is any fundamental understanding required for me, kindly suggest so.
Yes you are right Spring can invoke private constructor if you provide right arguments while defining the bean in configuration. But on question that comes to my mind is why would you do that if that bean is not meant to be instantiated?
It would be the case only say when you have helper class with static method or singleton etc. So it wont make sense to instantiate those classes.
But in your case, it's factory and you might be getting the object back by calling static method (accessing Static method/field doesn't necessarily need Object to access field/method) say getShape and you might be getting different shape based on parameter's that you might supply.
We sometimes need to use a class which was not designed for Spring and need to be instantiated via static factory method and Spring provides us with such possibility.
I am trying to auto generate some EJB service code, which are wrappers around Java DAO classes. DAO classes implement DAO interfaces, but also have their own public methods. This DAO layer is implemented by another team, so I cannot play around with it.
I am using CodeModel API to generate the code. I get each DAO class and want now to create the EJB Service code. Using java reflection I am trying to check if the method declared in the DAO class is an overridden implementing method of the interface or not. Is there anyway in which I can check that?
1) If overridden methods are with #Overridden annotation, than you could iterate through these methods, and check their annotation using this API: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/reflect/Method.html#getDeclaredAnnotations%28%29
2) If there are no annotations, I think, the only way is to iterate through parent classes and interfaces and compare method signatures, declared there with signatures in your class.
I am storing a list of classes through (Classname.class) and would like to instantiate one? Is this possible?
newInstance seems to the method I am after but it doesn't support a constructor?
You can use Class.getConstructors (or Class.getConstructor) to get a list of available constructors, and invoke any of them with Constructor.newInstance, which does accept parameters.
Just to add one point I see missing:
You can invoke newInstance directly on the Class object if it has a public null constructor. (Null constructor is the constructor with no arguments.)
Otherwise, you can find constructors via Class.getConstructors() as others have said.
The Java tutorial on reflection covers this well. But yeah, basically Class.getConstructors, then Constructor.newInstance is where it's at.
Java is designed so you can never "trick" it as long as you use the java.lang/java. classes or other standard libraries. One of the most important things of OOP is that objects should be in a defined state, thus you can be safe that the constructor is always run. Even if you're using some strange-looking reflection libraries to get your work done.
So, using Class.forName("me.Test").newInstance(); (or similar) will under-the-hood invoke the Test() constructor for you.
If you want to invoke another constructor the code is something like:
Test test = (Test)Class.forName("Test").getConstructor(String.class).newInstance("Hello World");
Here the getConstructor asks what the constructor looks like (it wants a string) and then you call it with a string.
You cannot construct new classes this way.
If you have the name of a class you can use Class.forName(className) to load/reference a class.
If you have the byte code for a class you want to create you can have a class loader load the byte code and give you the class. This is likely to be more advanced than you intended.
If you have a list of Class objects obtained through class literals, you might as well statically reference the constructors rather than slipping into reflection evilness.