Creating an Instance Using the Class Name and Calling Constructor

Creating an instance using the class name and calling constructor

Yes, something like:

Class<?> clazz = Class.forName(className);
Constructor<?> ctor = clazz.getConstructor(String.class);
Object object = ctor.newInstance(new Object[] { ctorArgument });

That will only work for a single string parameter of course, but you can modify it pretty easily.

Note that the class name has to be a fully-qualified one, i.e. including the namespace. For nested classes, you need to use a dollar (as that's what the compiler uses). For example:

package foo;

public class Outer
{
public static class Nested {}
}

To obtain the Class object for that, you'd need Class.forName("foo.Outer$Nested").

Java create new instance of class based on another class

You could do something like this:

Animal.java

public interface Animal {
}

Cat.java:

public class Cat implements Animal {
}

Dog.java:

public class Dog implements Animal {
}

Code to do the mapping:

Animal[] animals1 = new Animal[] {new Cat(), new Dog()};
Animal[] animals2 = Arrays.stream(animals1).map(a -> {
Animal animal = null;
try {
animal = a.getClass().getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return animal;
}).toArray(Animal[]::new);

Make a class instance from string and call a constructor

To answer the question as posted:

  1. Thats ok! Using this overload of Activator.CreateInstance: MSDN you can pass an object[] in, and it will find the constructor that best fits. Having a default constructor is a good idea though, especially if you are going to utilize serialization.

  2. You can't "handle" it in the sense that you can avoid it from happening. However, your code as written will throw an InvalidCastException if the cast fails. To avoid that, use the as operator:

    Action action = Activator.CreateInstance(t) as Action;

    Now action will just hold null if the cast is invalid, instead of throwing.

Now for the caveat: Activator.CreateInstance is very rarely the right choice in C#. In general, you want to use direct instantiation or deserialization. Granted, deserialization utilizes reflection; but all the messy details are abstracted away.

Getting class name of instance and using it to create new instances in JS

claName is a string, not a function. The constructor function is inst1.constructor, call that.

class Test {
constructor() {
console.log("constructing a Test");
}
}

inst1 = new Test();
cls = inst1.constructor;
inst2 = new cls;

Using the class type of an object to create a new instance

To realise the line Clazz user = (Clazz) o;, in the save method, where Clazz is the class of the object passed to the save method, so in this case User, you can make use of generics in the signature of save as follows:

public <T> void save(T user) throws IllegalAccessException, InstantiationException, InvocationTargetException {
int i = 0;
List<Object> args = new ArrayList<>();
args.add(0,"Example");
T newUser = (T)user.getClass().getConstructors()[i].newInstance(args);
// Exciting things...
}

Note that the type of newUser is inferred from the type of object passed to the method, and that you will need to know what objects are expected to be passed to the constructor of that type, to create the args array, otherwise an exception will be thrown. Similarly you'll need to know the position of the constructor in the array in order to set i.

In short, you need to be sure what kind of constructor the user argument will have, otherwise you'll run into troubles.

However, I believe this answers your question.

Is there a way to instantiate a class by name in Java?

Two ways:

Method 1 - only for classes having a no-arg constructor

If your class has a no-arg constructor, you can get a Class object using Class.forName() and use the newInstance() method to create an instance (though beware that this method is often considered evil because it can defeat Java's checked exceptions).

For example:

Class<?> clazz = Class.forName("java.util.Date");
Object date = clazz.newInstance();

Method 2

An alternative safer approach which also works if the class doesn't have any no-arg constructors is to query your class object to get its Constructor object and call a newInstance() method on this object:

Class<?> clazz = Class.forName("com.foo.MyClass");
Constructor<?> constructor = clazz.getConstructor(String.class, Integer.class);
Object instance = constructor.newInstance("stringparam", 42);

Both methods are known as reflection. You will typically have to catch the various exceptions which can occur, including things like:

  • the JVM can't find or can't load your class
  • the class you're trying to instantiate doesn't have the right sort of constructors
  • the constructor itself threw an exception
  • the constructor you're trying to invoke isn't public
  • a security manager has been installed and is preventing reflection from occurring


Related Topics



Leave a reply



Submit