Saturday, 15 September 2018

Different ways to dynamically load a class

In this post, I am going to explain how to load a class dynamically.
a.   Using Class.forName method
b.   Using ClassLoader

Using Class.forName method
'java.lang.Class' provides forName method to dynalically load a class. 'forName' method is available in overloaded forms.

public static Class<?> forName(String className) throws ClassNotFoundException
public static Class<?> forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException
This method returns the Class object associated with the class or interface with the given string name.

Below table summarizes the arguments of forName method.
Argument
Description
className
Fully qualified name of the class
initialize
If true the class will be initialized.
loader
Class loader from which the class must be loaded

Example
Class<?> clazz = Class.forName("com.sample.model.Employee");
Employee emp = (Employee)clazz.newInstance();

Above statements load the class Employee at run time.

Find the below working example.

Employee.java
package com.sample.model;

public class Employee {
 private int id;
 private String firstName;
 private String lastName;

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 @Override
 public String toString() {
  return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + "]";
 }

}

Application.java
package com.sample.app;

import com.sample.model.Employee;

public class Application {

 public static void main(String args[]) throws Exception {
  Class<?> clazz = Class.forName("com.sample.model.Employee");
  
  Employee emp = (Employee)clazz.newInstance();
  
  emp.setFirstName("Krishna");
  emp.setLastName("Maj");
  emp.setId(1);
  
  System.out.println(emp);
 }
}

Output
Employee [id=1, firstName=Krishna, lastName=Maj]

Points to note
a. When you pass initialize argument to true, static block of the class is called, else not.


Employee.java
package com.sample.model;

public class Employee {
 private int id;
 private String firstName;
 private String lastName;

 static {
  System.out.println("Initializing the class");
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 @Override
 public String toString() {
  return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + "]";
 }

}

Application.java
package com.sample.app;

public class Application {

 public static void main(String args[]) throws Exception {
  Class<?> clazz1 = Class.forName("com.sample.model.Employee", false, Application.class.getClassLoader()); 
 }
}


When you ran above application, you do not see anything in the console.

Let’s set the ‘initialize’ argument to true and rerun the application.

Application.java
package com.sample.app;

public class Application {

 public static void main(String args[]) throws Exception {
  Class<?> clazz1 = Class.forName("com.sample.model.Employee", true, Application.class.getClassLoader()); 
 }
}

Output
Initializing the class

Using ClassLoader load method
'java.lang.ClassLoader' class provides below methods to load the class dynamically.
public Class<?> loadClass(String name)
protected Class<?> loadClass(String name, boolean resolve)

Example
ClassLoader classLoader = Application.class.getClassLoader();
Class<?> clazz = classLoader.loadClass("com.sample.model.Employee");

Find the below working example.

Employee.java
package com.sample.model;

public class Employee {
 private int id;
 private String firstName;
 private String lastName;

 static {
  System.out.println("Initializing the class");
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 @Override
 public String toString() {
  return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + "]";
 }

}

Application.java
package com.sample.app;

import com.sample.model.Employee;

public class Application {

 public static void main(String args[]) throws Exception {
  ClassLoader classLoader = Application.class.getClassLoader();
  Class<?> clazz = classLoader.loadClass("com.sample.model.Employee");

  System.out.println("Creating an object to the class Employee");

  Employee emp = (Employee) clazz.newInstance();

  emp.setId(1);
  emp.setFirstName("Krishna");
  emp.setLastName("Maj");

  System.out.println(emp);
 }
}


Output
Creating an object to the class Employee
Initializing the class
Employee [id=1, firstName=Krishna, lastName=Maj]


As you observe the ouput, loadClass method do not call the static initializer block, it is called when I requested for an object to the class Employee.

You may like

No comments:

Post a Comment