DEV Community

Java new vs newInstance()

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 new when 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

  • new is 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 new for 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!

Comments

No comments yet. Start the discussion.