Core Java

Create Java Objects Using Class Names

The Java Reflection API provides several methods to achieve this goal. Nevertheless, identifying the most appropriate one for the current situation can pose a challenge. To tackle this, let’s start with a simple approach and progressively enhance it to arrive at a more efficient solution. Let us delve into exploring Java objects made using Class names.

1. Create Objects Using Class Name

In Java, you can create objects using the class name through a process called reflection. Reflection allows you to examine or modify the runtime behavior of applications.

1.1 Example

Let’s assume you have a class called Person:

package com.javacodegeeks;

public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public void introduce() {
        System.out.println("Hello, my name is " + name);
    }
}

Now, you can dynamically create an instance of this class using its name:

package com.javacodegeeks;

import java.lang.reflect.Constructor;

public class ObjectCreationExample {

    public static void main(String[] args) {
        // Class name as a String
        String className = "Person";

        try {
            // Load the class dynamically
            Class<?> clazz = Class.forName(className);

            // Get the constructor with a String parameter
            Constructor<?> constructor = clazz.getConstructor(String.class);

            // Create an instance by invoking the constructor
            Object personObject = constructor.newInstance("John Doe");

            // Cast the object to the actual class
            Person johnDoe = (Person) personObject;

            // Call a method on the created object
            johnDoe.introduce();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

1.1.1 Explanation

  • Class.forName(className): Dynamically loads the class with the specified name.
  • clazz.getConstructor(String.class): Retrieves the constructor of the class that takes a String parameter.
  • constructor.newInstance("John Doe"): Invokes the constructor to create a new instance of the class with the provided parameter.
  • The created object is then cast to the actual class (Person in this case) so that you can use its methods.

Note: Using reflection for object creation can have performance implications and should be used judiciously. It’s typically preferable to create objects using the new keyword when you know the class at compile time.

2. Create Objects Using the Raw Class Object

In Java, it is possible to create objects dynamically using the raw class object. This approach can be useful in scenarios where the class name is known only at runtime. Here is the sequence of steps for creating objects using raw class instances:

  • Class.forName(className): Dynamically loads the class with the specified name.
  • clazz.newInstance(): Creates a new instance of the class using the default constructor.

2.1 Example

Here is an illustrative example:

package com.javacodegeeks;

import java.lang.Class;

public class ObjectCreationExample {

	public static void main(String[] args) {
		// Class name as a String
		String className = "Person";

		try {
			// Load the class dynamically
			Class<?> clazz = Class.forName(className);

			// Create an instance using the default constructor
			Object personObject = clazz.newInstance();

			// Cast the object to the actual class
			Person defaultPerson = (Person) personObject;

			// Call a method on the created object
			defaultPerson.defaultIntroduction();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

The above example demonstrates how to create an instance of a class using the raw class object. The newInstance() method is used to create an object using the default constructor of the class. The resulting object is initially of type Object and needs to be cast to the specific class (Person in this case). After the casting, the code calls the defaultIntroduction method on the created object, assuming that the Person class has this method. Any exceptions that might occur during this process are caught and printed using the catch block.

3. Create Objects Using Class Object and Generics

In Java, the Class object combined with Generics can be utilized to create objects dynamically with type safety. This approach is particularly beneficial when you want to instantiate objects with specific types at runtime. Here is the sequence of steps for creating objects using class objects and generics:

  • Class.forName(className): Dynamically loads the class with the specified name.
  • clazz.getDeclaredConstructor(parameterTypes): Retrieves the constructor of the class with specific parameter types.
  • constructor.newInstance(arguments): Invokes the constructor to create a new instance of the class with the provided arguments.

3.1 Example

Here is an illustrative example:

package com.javacodegeeks;

import java.lang.reflect.Constructor;

public class ObjectCreationExample {

	public static <T> T createObject(String className, Object... arguments) {
		try {
			// Load the class dynamically
			Class<?> clazz = Class.forName(className);

			// Get the constructor with specified parameter types
			Class<?>[] parameterTypes = new Class[arguments.length];
			for (int i = 0; i < arguments.length; i++) {
				parameterTypes[i] = arguments[i].getClass();
			}
			Constructor<?> constructor = clazz.getDeclaredConstructor(parameterTypes);

			// Create an instance by invoking the constructor
			return (T) constructor.newInstance(arguments);

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static void main(String[] args) {
		// Create an instance of Person with specific arguments
		Person johnDoe = createObject("Person", "John Doe");

		// Call a method on the created object
		johnDoe.introduce();
	}
}

The provided Java code defines a generic method createObject within the ObjectCreationExample class, which facilitates dynamic object creation with specified parameters. The method takes the class name as a string (className) and a variable number of arguments (arguments).

Inside the method, the code dynamically loads the class using Class.forName(className). It then extracts the types of the provided arguments and obtains the constructor of the class with the matching parameter types. Subsequently, an instance of the class is created by invoking the constructor with the specified arguments using constructor.newInstance(arguments).

The main method demonstrates the usage of the createObject method by creating an instance of the Person class named “johnDoe” with the argument “John Doe”. Finally, the introduce method is called on the created johnDoe object. Any exceptions during the process are caught and printed, and if an exception occurs, the method returns null.

4. Create Objects Using Type Parameter Extends

In Java, type parameters with the extends keyword can be employed to create objects with more flexibility and to ensure certain type constraints. This is useful when you want to work with a specific type or its subclasses. Here is the sequence of steps for creating objects using type parameter extends:

  • Class.forName(className) Dynamically loads the class with the specified name.
  • clazz.getDeclaredConstructor(parameterTypes) Retrieves the constructor of the class with specific parameter types.
  • constructor.newInstance(arguments) Invokes the constructor to create a new instance of the class with the provided arguments.

4.1 Example

Here is an illustrative example:

package com.javacodegeeks;

import java.lang.reflect.Constructor;

public class ObjectCreationExample {

	public static <T extends Person> T createPerson(String className, Object... arguments) {
		try {
			// Load the class dynamically
			Class<?> clazz = Class.forName(className);

			// Get the constructor with specified parameter types
			Class<?>[] parameterTypes = new Class[arguments.length];
			for (int i = 0; i < arguments.length; i++) {
				parameterTypes[i] = arguments[i].getClass();
			}
			Constructor<?> constructor = clazz.getDeclaredConstructor(parameterTypes);

			// Create an instance by invoking the constructor
			return (T) constructor.newInstance(arguments);

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static void main(String[] args) {
		// Create an instance of Person or its subclass with specific arguments
		Employee janeEmployee = createPerson("Employee", "Jane Doe", "HR");

		// Call a method on the created object
		janeEmployee.introduce();
	}
}

In the provided Java code, the ObjectCreationExample class includes a generic method called createPerson. This method is parameterized with a type parameter <T extends Person>, indicating that the type T must be a subclass of or the same as the Person class. This restriction ensures that the created objects are instances of the Person class or its subclasses.

Inside the createPerson method, the code dynamically loads a class specified by its name (className) using Class.forName(className). It then determines the types of the provided arguments and obtains the constructor of the class with the matching parameter types. Subsequently, an instance of the class is created by invoking the constructor with the specified arguments using constructor.newInstance(arguments).

In the main method, the code demonstrates the usage of the createPerson method by creating an instance of the Employee class named “janeEmployee” with the arguments “Jane Doe” and “HR”. Since Employee is a subclass of Person, it satisfies the type constraint specified in the createPerson method. Finally, the introduce method is called on the created janeEmployee object. Any exceptions during the process are caught and printed, and if an exception occurs, the method returns null.

5. Conclusion

In conclusion, the ability to dynamically create objects in Java provides a powerful and flexible approach to programming. The use of the Class object, combined with generics and type parameters, allows developers to instantiate objects at runtime with varying degrees of flexibility and type safety. Whether employing the raw class object for simpler scenarios or leveraging generics with extends to enforce type constraints, these techniques enable the creation of objects in a dynamic and adaptable manner. It’s important to note that while these dynamic object-creation techniques offer versatility, they should be used judiciously. Considerations such as performance implications and code maintainability should guide the decision to opt for dynamic instantiation. Ultimately, understanding these approaches equips developers with valuable tools to address dynamic object creation requirements in Java applications.

Yatin

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button