Creating objects is one of the most fundamental operations in Java.
Most developers use the new operator every day, but Java also allows objects to be created dynamically using Reflection.
Understanding the difference between new and newInstance() is a common Java interview question.
In this article, we'll compare both approaches, explain when to use each, discuss exceptions, and cover the modern replacement for the deprecated Class.newInstance() method.
What is new?
The new keyword is a Java operator used to create objects when the class is known at compile time.
Test test = new Test();
When Java executes new, it:
- Allocates memory on the heap
- Invokes the constructor
- Returns a reference to the newly created object
What is newInstance()?
newInstance() is a reflection-based method used to create objects when the class name is available only at runtime.
Historically, it was called like this:
Object obj = Class.forName("com.example.Test").newInstance();
However, Class.newInstance() has been deprecated since Java 9.
The recommended approach is:
Object obj = Class.forName("com.example.Test")
.getDeclaredConstructor()
.newInstance();
This approach is safer and provides better exception handling.
Quick Comparison
| Feature | new |
newInstance() |
|---|---|---|
| Type | Operator | Reflection method |
| Class known | Compile time | Runtime |
| Uses reflection | ❌ No | ✅ Yes |
| Constructor called | Directly | Via reflection |
| Recommended today | ✅ Yes | Use Constructor.newInstance() instead of Class.newInstance()
|
Using new
class Test {
public Test() {
System.out.println("Constructor called");
}
public static void main(String[] args) {
Test test = new Test();
}
}
Output
Constructor called
The compiler already knows the class name.
Using Reflection
Suppose the class name is provided at runtime.
public class Demo {
public static void main(String[] args) throws Exception {
Object obj = Class.forName(args[0])
.getDeclaredConstructor()
.newInstance();
System.out.println(obj.getClass().getName());
}
}
Execution
java Demo java.lang.String
Output
java.lang.String
Run again
java Demo java.lang.Thread
Output
java.lang.Thread
Notice that the program never changes.
Only the class name changes.
This is the power of Reflection.
Compile-Time vs Runtime
With new
Test test = new Test();
The class name is fixed.
With Reflection
Class.forName(className)
The class can be chosen dynamically.
Constructor Requirement
Using new
You can call any accessible constructor.
Test t1 = new Test();
Test t2 = new Test("Rajesh");
Test t3 = new Test(100);
Using Reflection
The simplest reflective creation requires an accessible no-argument constructor.
Object obj = Class.forName("Test")
.getDeclaredConstructor()
.newInstance();
If no no-argument constructor exists, getDeclaredConstructor() (or the invocation) will fail.
You can also invoke parameterized constructors reflectively:
Test obj = Test.class
.getDeclaredConstructor(String.class)
.newInstance("Rajesh");
What Happens If the Class Is Missing?
Using new
Test t = new Test();
If the class cannot be loaded at runtime, Java throws
NoClassDefFoundError
This is an unchecked Error.
Using Reflection
Class.forName("Test");
If the class cannot be found,
Java throws
ClassNotFoundException
This is a checked exception.
Exception Comparison
| Situation | new |
Reflection |
|---|---|---|
| Missing class | NoClassDefFoundError |
ClassNotFoundException |
| Exception type | Unchecked Error | Checked Exception |
Why Was Class.newInstance() Deprecated?
Before Java 9, developers commonly wrote:
Object obj = Class.forName("Test").newInstance();
The problem was that it:
- worked only with an accessible no-argument constructor,
- had poor exception handling,
- propagated constructor exceptions in a confusing way.
Since Java 9, the recommended approach is:
Object obj = Class.forName("Test")
.getDeclaredConstructor()
.newInstance();
This API provides better exception handling and greater flexibility.
Real-World Use Cases
Reflection-based object creation is common in many Java frameworks.
Examples include:
- Loading JDBC drivers dynamically
- Dependency Injection containers
- Spring Framework
- Hibernate
- Plugin architectures
- Reflection utilities
- Configuration-based object creation
Interview Questions
Which one is faster?
new
Reflection performs additional runtime checks.
Which one is type-safe?
new
Reflection returns Object, so casting is often required.
Which one should be used most of the time?
new
Reflection should only be used when dynamic class loading is actually required.
Is Class.newInstance() still recommended?
No.
Use
getDeclaredConstructor().newInstance()
instead.
Memory Trick 🧠
Remember this simple rule:
Use
newwhen you KNOW the class. Use Reflection when you DISCOVER the class at runtime.
Or even shorter:
new
↓
Known class
Reflection
↓
Dynamic class
Quick Comparison Table
| Feature | new |
Reflection (Constructor.newInstance()) |
|---|---|---|
| Type | Operator | Method |
| Class name | Known at compile time | Known at runtime |
| Reflection | ❌ | ✅ |
| Constructor | Any accessible constructor | Any accessible constructor obtained reflectively |
| Performance | Faster | Slower |
| Type safety | Strong | Requires casting |
| Common usage | Everyday Java programming | Frameworks, plugins, dependency injection |
Key Takeaways
-
newis the standard way to create objects when the class is known at compile time. - Reflection allows object creation when the class name is determined at runtime.
-
Class.newInstance()has been deprecated since Java 9. - The recommended approach is
getDeclaredConstructor().newInstance(). - Reflection is widely used by frameworks like Spring and Hibernate.
- Use
newfor normal application code and Reflection only when dynamic object creation is required.
If you found this guide helpful, leave a ❤️ and follow for more beginner-friendly Java tutorials, interview questions, and practical coding examples.
Happy Coding!
Top comments (0)