How do i create a new instance of an object from a string?
I want to do this:
Event event = new Event("hello");
event.setName("nice!");
but only having
String object = "Event";
String object_variable_name = "event";
String object_params = "hello";
Is this possible?
You can instantiate a class with the reflection API. But you need the full class name, the simple name (= with no constructor) is not enough.
Class clazz = Class.forName("com.example.Event");
Constructor constructor = clazz.getConstructor(String.class);
Object instance = constructor.newInstance("hello");
Assigning it to a variable where the variables name and type are stored in Strings is not possible. The usual pattern to implement this is to use a map:
Map<String, Object> events = new HashMap<String, Object>();
events.put("event", event);
You can use java.lang.Class's getConstructor isnstead.
Here is how you get the class instance (so you can call the constructor): How to get a Class Object from the Class Name in Java
Now you can you the Beans API to get the getter for the property name. See this question: Java Reflection: Instantiate a new object with specified type
Or you can use reflectasm or reflections or commons-beanutils to make your life much more simple
Related
I am making a program that lets the user call a class, like it takes a string input, then calls the run() method of that class, is there any way to do that? I was hoping something like:
String inp=new Scanner(System.in).nextLine();
Class cl=new Class(inp);
cl.run();
I know that the code isn't correct, but that is my main idea
Creating and using a class by name requires some preconditions:
Full name of the class must be used, including package name.
You need to know the parameters of the constructor. Usually the no-arguments constructor is used for a such use case.
(Optional) You need an interface this class must implement which declares the method "run" (or any other methods you want to use).
An example with a subclass of Runnable:
String className = "some.classname.comes.from.Client";
Class<Runnable> clazz = (Class<Runnable>) Class.forName(className);
Runnable instance = clazz.getConstructor().newInstance();
instance.run();
If you don't have a common interface, you can invoke the method using reflection:
Class<Object> clazz = (Class<Object>) Class.forName(className);
Object instance = clazz.getConstructor().newInstance();
clazz.getMethod("run").invoke(instance);
or using method with parameters:
Integer p1 = 1;
int p2 = 2;
clazz.getMethod("methodWithParams", Integer.class, Integer.TYPE).invoke(instance, p1, p2);
String Variable can't be a reference for the Class.
to to a something like changing the object depends on the input
you can use polymorphism and design patterns (Factory Pattern)
I need help I need to know if Java allows to create an object dynamically, using the value of a variable.
Example
// I have 2 classes:
public class Audit {
private Long idAudit
// constructors, get and set
}
publish class Example {
private Long idExample
// constructors, get and set
}
-------------------------------------------------- -----
// create Audit and Example class object
Audit objAudit = new Audit ();
Example objExample = new Example ();
my question is the following can you create an object either of type Audit or example using the value of a variable as I try to do in the following example. Example:
String className = "Audit"; // variable that contains the class of the Object to create
className auditObject = new ClassName (); // I use the variable classname to create the desired object
Clearly I get an error trying to create the object that way, my question is can I create an object dynamically or some other option to try to achieve what I need. Thank you
Reflection is what you are searching for
final String className = "Audit";
final Class<?> clazz = Class.forName(className);
final Object o = clazz.getConstructor().newInstance();
There are several ways you can do this.
One is called reflection, and I will let you read about it on your own.
The other one is called a factory pattern. You can create a class called ObjectFactory. in that class you will have a method public Object createObject(String type).
In the method you can check if the type you received is one of your known types, and based on the type you can create the instance of the correct class. It is better of your classes implement the same interface. Then of course your method would return the instance of that interface (or a common base class).
I have two classes in java. I am calling a method of 2nd class from 1st class when the 2nd class name is stored in a string variable.
I tried the below code.It creates the class.
String adapterClass = "com.appzillon.server.impl.ViewAccDtlsAdapterImpl";
Class className = Class.forName(adapterClass);
After that how to call the method.Method name is getInfo with a string type paramater.
Method method = className.getDeclaredMethod("getInfo", String.class);
method.invoke(instance, "your parameter");
Where instance is either:
Object instance = null;
if the method is static. Or:
Object instance = className.getDeclaredConstructor().newInstance();
If the method is a member method
For scenarios like these, you can very well use Java Reflection APIs.
Class classInstance = Class.forName(<your class name>);
Methoed methodHandle = classInstance.getMethod(<methodName>,<arguments classes>);
Object returnValue = methodHandle.invoke(null, "parameter-value1");
Note : The null parameter is the object you want to invoke the method on. If the method is static you supply null instead of an object instance
Though my question seems repetition, but I am new to Reflections and could find solution to the exact problem.
I need to write a method, which any class can call to populate its data. For simplicity, I created a class say MappingHelper, with a Factory like method 'Create' which will create its own instance. I need to then populate this instance and return it.
public final Class MappingHelper{
public final Object getBENodeData(Class<?> classRef, String className){
Class myClass = Class.forName(classRef.getName());
Method method = classRef.getMethod("Create",(Class<?>[])null);
Object obj = method.invoke(null, (Object[]) null);
}
}
I need to typecast obj to same type as of 'classRef' so that I can call its instance methods.
Could someone help?
What you're trying to do is not possible with reflection and with your current setup. Even if you manage to cast the object to classRef, you wouldn't know what instance methods to call since getBENodeData presumably can take any type.
What you can do is call the method from a location where the type is known, and cast to it.
Object obj = getBENodeData(MyType1.class, MyType1.class.getName());
MyType1 myType1 = (MyType1) obj;
myType1.setId(..);
Object obj2 = getBENodeData(MyType2.class, MyType2.class.getName());
MyType2 myType2 = (MyType2) obj2;
myType2.setName(..);
Example :
List<String> list = new ArrayList<String>();
//This would give me the class name for the list reference variable.
list.getClass().getSimpleName();
I want to get the Interface name from the list reference variable.
Is there any way possible to do that?
Using Reflection you can invoke the Class.getInterfaces() method which returns an Array of Interfaces that your class implements.
list.getClass().getInterfaces()[0];
To get just the name
list.getClass().getInterfaces()[0].getSimpleName();
Class aClass = ... //obtain Class object.
Class[] interfaces = aClass.getInterfaces();