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
Instantiate object from class name as string
You can create an instance of a class and run its methods without ever having to import the class in your code using reflection:
Class clazz = Class.forName("com.whatever.MyClass");
Object instance = clazz.newInstance(); // or use the given instance
clazz.getMethod("myMethod").invoke(instance);
Java how to instantiate a class from string
"Using java.lang.reflect
" will answer all your questions. First fetch the Class
object using Class.forName()
, and then:
If I want to instantiate a class that I retrieved with
forName()
, I have to first ask it for ajava.lang.reflect.Constructor
object representing the constructor I want, and then ask thatConstructor
to make a new object. The methodgetConstructor(Class[] parameterTypes)
inClass
will retrieve aConstructor
; I can then use thatConstructor
by calling its methodnewInstance(Object[] parameters)
:Class myClass = Class.forName("MyClass");
Class[] types = {Double.TYPE, this.getClass()};
Constructor constructor = myClass.getConstructor(types);
Object[] parameters = {new Double(0), this};
Object instanceOfMyClass = constructor.newInstance(parameters);
There is a newInstance()
method on Class
that might seem to do what you want. Do not use it. It silently converts checked exceptions to unchecked exceptions.
Note that this method propagates any exception thrown by the nullary constructor, including a checked exception. Use of this method effectively bypasses the compile-time exception checking that would otherwise be performed by the compiler. The
Constructor.newInstance
method avoids this problem by wrapping any exception thrown by the constructor in a (checked)InvocationTargetException
.
Using a string to instantiate a class
I'm not sure I understand correctly, seems weird no one else mentioned this yet:
Map<Character, ShapeFactory> dict = new HashMap<>();
dict.put('C', new CircleFactory());
dict.put('R', new RectangleFactory());
dict.put('T', new TriangleFactory());
...
ShapeFactory factory = dict.get(symbol);
Shape shape = factory.create(data);
Can I Instantiate a class using the class object? What about Constructors?
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.
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")
.
Related Topics
Does Java Have Support for Multiline Strings
Jrbeancollectiondatasource: How to Show Data from the Java.Util.List from Javabean
What Is the Correct Way to Structure This Kind of Data in Firestore
How to Have an Autocomplete Using Jtextfield and a Jlist
How to Write a Utf-8 File with Java
How to Use a Custom Serializer with Jackson
Java String Split with "." (Dot)
Java: Insert Multiple Rows into MySQL with Preparedstatement
What Is Variable Shadowing Used for in a Java Class
How to Switch to the New Browser Window, Which Opens After Click on the Button
Under What Conditions Is a Jsessionid Created
Difference Between String Replace() and Replaceall()
Hibernate Annotations - Which Is Better, Field or Property Access