eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – Summer Sale 2026 – NPI EA (cat= Baeldung)
announcement - icon

Yes, we're now running our only Summer Sale. All Courses are 30% off until 20th July, 2026:

>> EXPLORE ACCESS NOW

Course – Summer Sale 2026 – NPI (cat=Baeldung)
announcement - icon

Yes, we're now running our only Summer Sale. All Courses are 30% off until 20th July, 2026:

>> EXPLORE ACCESS NOW

1. Overview

In this tutorial, we’ll explore the process of creating Java objects using their class names. The Java Reflection API offers various methods for accomplishing this task. However, determining the most suitable one for the current context can be challenging.

To address this, let’s begin with a straightforward approach and gradually refine it to a more efficient solution.

2. Create Objects Using Class Name

Let’s picture a motor service center. This center handles maintenance and repairs for motor vehicles, using job cards to categorize and manage service requests. We can represent this as a class diagram:

Bronze

Let’s take a look at the MaintenanceJob and RepairJob classes:

public class MaintenanceJob {
    public String getJobType() {
        return "Maintenance Job";
    }
}
public class RepairJob {
    public String getJobType() {
        return "Repair Job";
    }
}

Now, let’s implement the BronzeJobCard:

public class BronzeJobCard {
    private Object jobType;
    public void setJobType(String jobType) throws ClassNotFoundException,
            NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class jobTypeClass = Class.forName(jobType);
        this.jobType = jobTypeClass.getDeclaredConstructor().newInstance();
    }

    public String startJob() {
        if(this.jobType instanceof RepairJob) {
            return "Start Bronze " + ((RepairJob) this.jobType).getJobType();
        }
        if(this.jobType instanceof MaintenanceJob) {
            return "Start Bronze " + ((MaintenanceJob) this.jobType).getJobType();
        }
        return "Bronze Job Failed";
    }
}

In BronzeJobCard, Class.forName() takes the fully qualified name of the class to return the raw job object. Later, startJob() uses type-casting on the raw object to get the correct job type. On top of these disadvantages, there is also the overhead of handling the exceptions.

Let’s see it in action:

@Test
public void givenBronzeJobCard_whenJobTypeRepairAndMaintenance_thenStartJob() throws ClassNotFoundException,
  InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {

    BronzeJobCard bronzeJobCard1 = new BronzeJobCard();
    bronzeJobCard1.setJobType("com.baeldung.reflection.createobject.basic.RepairJob");
    assertEquals("Start Bronze Repair Job", bronzeJobCard1.startJob());

    BronzeJobCard bronzeJobCard2 = new BronzeJobCard();
    bronzeJobCard2.setJobType("com.baeldung.reflection.createobject.basic.MaintenanceJob");
    assertEquals("Start Bronze Maintenance Job", bronzeJobCard2.startJob());
}

So, the above method started two Jobs, a repair job and a maintenance job.

A few months later, the service center decided to start a paint job as well. So, we created a new class PaintJob, but can BronzeJobCard accommodate this new addition? Let’s see:

@Test
public void givenBronzeJobCard_whenJobTypePaint_thenFailJob() throws ClassNotFoundException,
  InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {

    BronzeJobCard bronzeJobCard = new BronzeJobCard();
    bronzeJobCard.setJobType("com.baeldung.reflection.createobject.basic.PaintJob");
    assertEquals("Bronze Job Failed", bronzeJobCard.startJob());
}

That failed miserably! Due to the use of raw objects, BronzeJobCard is unable to handle the new PaintJob.

3. Create Objects Using the Raw Class Object

In this section, we’ll upgrade the Job card to create the jobs using java.lang.Class instead of the name of the class. First, take a look at the class diagram:

 

Silver

Let’s see how different SilverJobCard is from the BronzeJobCard:

public class SilverJobCard {
    private Object jobType;

    public void setJobType(Class jobTypeClass) throws
      NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        this.jobType = jobTypeClass.getDeclaredConstructor().newInstance();
    }

    public String startJob() {
        if (this.jobType instanceof RepairJob) {
            return "Start Silver " + ((RepairJob) this.jobType).getJobType();
        }
        if (this.jobType instanceof MaintenanceJob) {
            return "Start Silver " + ((MaintenanceJob) this.jobType).getJobType();
        }
        return "Silver Job Failed";
    }
}

It no longer relies on the fully qualified name of the job classes to create the objects. However, the issue with raw objects and exceptions remains unchanged.

As shown below, it can also handle creating the jobs and then starting them:

@Test
public void givenSilverJobCard_whenJobTypeRepairAndMaintenance_thenStartJob() throws InvocationTargetException,
  NoSuchMethodException, InstantiationException, IllegalAccessException {

    SilverJobCard silverJobCard1 = new SilverJobCard();
    silverJobCard1.setJobType(RepairJob.class);
    assertEquals("Start Silver Repair Job", silverJobCard1.startJob());

    SilverJobCard silverJobCard2 = new SilverJobCard();
    silverJobCard2.setJobType(MaintenanceJob.class);
    assertEquals("Start Silver Maintenance Job", silverJobCard2.startJob());
}

But, like BronzeJobCard, SilverJobCard also fails to accommodate the new PaintJob:

@Test
public void givenSilverJobCard_whenJobTypePaint_thenFailJob() throws ClassNotFoundException,
  InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {

    SilverJobCard silverJobCard = new SilverJobCard();
    silverJobCard.setJobType(PaintJob.class);
    assertEquals("Silver Job Failed", silverJobCard.startJob());
}

Also, the method setJobType() does not restrict the passing of any object other than RepairJob and MaintenanceJob. This might result in erroneous code during the development stage.

4. Create Objects Using Class Object and Generics

Earlier, we saw how raw objects are affecting the quality of the code. In this section, we’ll address it. But first, take a look at the class diagram:

 

Gold

This time, we got rid of the raw objects. GoldJobCard takes the type parameter and makes use of Generics in the method setJobType(). Let’s check the implementation:

public class GoldJobCard<T> {
    private T jobType;

    public void setJobType(Class<T> jobTypeClass) throws
      NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        this.jobType = jobTypeClass.getDeclaredConstructor().newInstance();
    }

    public String startJob() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        return "Start Gold " + this.jobType.getClass().getMethod("getJobType", null)
                .invoke(this.jobType).toString();
    }
}

Interestingly, startJob() is now invoking the method on the object using the Reflection API. Finally, we also got rid of the need for type-casting. Let’s see how it behaves:

@Test
public void givenGoldJobCard_whenJobTypeRepairMaintenanceAndPaint_thenStartJob() throws InvocationTargetException,
  NoSuchMethodException, InstantiationException, IllegalAccessException {

    GoldJobCard<RepairJob> goldJobCard1 = new GoldJobCard();
    goldJobCard1.setJobType(RepairJob.class);
    assertEquals("Start Gold Repair Job", goldJobCard1.startJob());

    GoldJobCard<MaintenanceJob> goldJobCard2 = new GoldJobCard();
    goldJobCard2.setJobType(MaintenanceJob.class);
    assertEquals("Start Gold Maintenance Job", goldJobCard2.startJob());

    GoldJobCard<PaintJob> goldJobCard3 = new GoldJobCard();
    goldJobCard3.setJobType(PaintJob.class);
    assertEquals("Start Gold Paint Job", goldJobCard3.startJob());
}

Here, it handles the PaintJob as well.

But still, we’re not able to restrict the objects passed into the startJob() method during the development phase. As a result, it would fail for an object that does not have the getJobType() method like MaintenanceJob, RepairJob, and PaintJob.

5. Create Objects Using Type Parameter Extends

It’s time to address the issue raised earlier. Let’s start with the customary class diagram:

 

Platinum

We’ve introduced the Job interface, which all Job objects must implement. Furthermore, PlatinumJobCard now accepts only Job objects, indicated by the T extends Job parameter.

Actually, this approach closely resembles the Factory Design Pattern. We can introduce a JobCardFactory that can handle the creation of the Job objects.

Moving on, we can now look at the implementation:

public class PlatinumJobCard<T extends Job> {
    private T jobType;

    public void setJobType(Class<T> jobTypeClass) throws
      NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        this.jobType = jobTypeClass.getDeclaredConstructor().newInstance();
    }

    public String startJob() {
        return "Start Platinum " + this.jobType.getJobType();
    }
}

We got rid of the Reflection API and the type-casting from the startJob() method by introducing the Job interface. Thankfully, now PlatinumJobCard will be able to handle future Job types without any modification to it. Let’s see it in action:

@Test
public void givenPlatinumJobCard_whenJobTypeRepairMaintenanceAndPaint_thenStartJob() throws InvocationTargetException,
  NoSuchMethodException, InstantiationException, IllegalAccessException {

    PlatinumJobCard<RepairJob> platinumJobCard1 = new PlatinumJobCard();
    platinumJobCard1.setJobType(RepairJob.class);
    assertEquals("Start Platinum Repair Job", platinumJobCard1.startJob());

    PlatinumJobCard<MaintenanceJob> platinumJobCard2 = new PlatinumJobCard();
    platinumJobCard2.setJobType(MaintenanceJob.class);
    assertEquals("Start Platinum Maintenance Job", platinumJobCard2.startJob());

    PlatinumJobCard<PaintJob> platinumJobCard3 = new PlatinumJobCard();
    platinumJobCard3.setJobType(PaintJob.class);
    assertEquals("Start Platinum Paint Job", platinumJobCard3.startJob());
}

6. Conclusion

In this article, we explored the various ways to create objects with the class name and the Class object. We showed how related objects can implement a base interface. Then, it can be used further to streamline the object creation process. With this approach, there’s no need for type-casting, and also, it ensures the use of the Job interface, enforcing type-checking during development.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

Course – Summer Sale 2026 – NPI EA (cat= Baeldung)
announcement - icon

Yes, we're now running our only Summer Sale. All Courses are 30% off until 20th July, 2026:

>> EXPLORE ACCESS NOW

Course – Summer Sale 2026 – NPI (All)
announcement - icon

Yes, we're now running our only Summer Sale. All Courses are 30% off until 20th July, 2026:

>> EXPLORE ACCESS NOW

eBook Jackson – NPI EA – 3 (cat = Jackson)