Reflection in Java

ReflectionExceptionsResources

In the previous blog we have learned about the Wrapper Classes in Java. If you want to know about the Wrapper Classes visit Wrapper Classes in Java. In this blog, we will learn about Reflection in Java. The reflection feature in Java lets running Java code inspect or reflect on itself and change the program's internal attributes. The reflective library provides a rich and elaborate toolset for writing programs that dynamically manipulate Java code. With the help of reflection, Java can support user interface builders, object-relational mappers, and many other development tools that dynamically inquire about the capabilities of classes. The Reflection mechanism is very powerful. Reflection allows us to runtime inspect objects, runtime analyze capabilities classes, runtime construct generic array manipulation code, and runtime utilize Method objects that function merely like function pointers in languages like C++. We will go through the details:

Java Class class

While the code is running, the Java runtime system maintains runtime type identification on all objects. This information keeps track of the class to which each object belongs. Virtual Machine uses Runtime type information to select the correct methods to execute. We can access this information using the Java class. The class that holds this information is called Class. The method of Object class i.e. getClass() method returns an instance of the Class type.

e.g.

AtrowelEmployee atrowelObj;
.......
Class classObj = atrowelObj.gelClass();

In the above example AtrowelEmployee object describes the properties of the AtrowelEmplyee, same is the case with the Class object which describes the properties of the class. The getName() method of Class is the most commonly used method. This method returns the name of the class.

e.g.

System.out.println(atrowelObj.getClass().getName() + " " + atrowelObj.getName());

The above statement prints:

e.g.

Employee Smith Wiliams

Suppose if the class is in the package, then the package name will be part of the class name.

e.g.

var generator = new Random(); // set to java.util.Random
Class cl = generator.getClass();
String name = cl.getName();

We can get the Class object corresponding to the class name by using the forName() method.

e.g.

String className = "java.util.Random";
Class cl = Class.forName(className);

forName() method is useful only if the class name is stored in the string that varies at runtime. It will work only when the classname is the name of the class or interface.

The other method for obtaining an object of type Class is a shorthand. For example, if A is a Java type , then A.class is the matching object of A class

e.g.

Class classObj1 = Random.class; // if we import java.util.*;
Class classObj2 = int.class;
Class classObj3 = Double[].class;

Please note that a Class object describes a type, which may or may not be a class. For example, int or float are not classes but int.class or float.class is nonetheless an object of type Class. The virtual machine manages a Class object for each type. We can use the == to compare class objects.

e.g.

if(atrowelObj.getClass() == AtrowelEmployee.class) . . .

The above statement passes if atrowelObj is an instance of class AtrowelEmployee. The condition atrowelObj instanceof AtrowelEmployee, this condition fails if atrowelObj is an instance of a subclass such as AtrowelManager. If we have an object to type Cass, then we can make use of it to construct the instances of the class. To get an object of type Constructor we can use the getConstructor() method and to construct an instance we can use the newInstance() method.

e.g.

var className = "java.util.Random";
Class cl = Class.forName(className);
Object obj = cl.getConstructor().newInstance();

Suppose the class doesn’t have a constructor without an argument then the getConstructor() method will throw an exception.


Exceptions in Java

Many times we have seen the methods throwing an exception. When an error occurs at runtime, then the program may throw an exception. It is more feasible to throw an exception rather than terminating the program because we can provide a handler that can catch the exception and deal with it. If suppose there is no handler provided, then the program will terminate and will print the message in the console with the type of exception. We are already familiar with the NullPointer exception and ArrayIndexOutOfBound exception. There are two types of exceptions: checked exceptions and unchecked exceptions. In unchecked exceptions, the compiler checks whether the programmer is aware of the exception and is prepared to deal with the consequences. NullPointer Exception and ArrayIndexOutOfBound exceptions are unchecked exceptions. Whenever a method contains a statement that might throw a checked exception, then we must add a throws clause to the method name.

e.g.

public static void displayException(String ename) throws ReflectiveOperationException{
    Class classObj = Class.forName(ename); // may throw exception
}

Any method which will call this method will also require to add a throws declaration. For example main() method. If the exception occurs, then the main() method terminates with a stack trace. We only need to supply a throws clause for checked exceptions. It is easy to find out which methods throw checked exceptions: the compiler will complain whenever we call a method that threatens to throw a checked exception and we don’t supply a handler.


Resources in Java

Classes have associated data files, such as

  1. Source Files and Image
  2. Text files with message string and button labels.

Such an associated file is called a resource. The Class class provides a service for locating files. Following are the necessary steps:

  1. The first step is to get the Class object of the class which has a resource for example AtrowelResourceTest.class
  2. Methods like the getImage() method of ImageIcon accept the described location. Then we can call by the following:

    e.g.

    URL url = cl.getResource("about.gif");
  3. Or else, use the getResourceAsStream() method to obtain an input stream for reading the data in the file.

As the JVM knows how to locate a class, it can search for the associated resource in the same location. For example suppose For example, suppose the AtrowelResourceTest class is in a package resource, then the ResourceTest.class file is located in a resources directory, and we can place an icon file into the same directory. Rather than placing a resource file inside the same directory as the class file, you can provide a relative or absolute path. Another common application of resources is the internationalization of the program. Language-dependent strings such as user interface labels and messages are stored in the resource files. The internationalization supports the method for organizing and accessing these localization

e.g.

import java.io.*;
import java.net.*;
import java.nio.charset.*;
import javax.swing.*;
public class AtrowelResourceTest{
  public static void main(String[] args) throws IOException{
    Class classObj = AtrowelResourceTest.class;
    URL atrowelAboutURL = classObj.getResource("About.gif");
    var icon = new ImageIcon(atrowelAboutURL);
    InputStream inputStream = classObj.getResourceAsStream("data/about.txt");
    var about = new String(inputStream.readAllBytes(), "UTF-8");
    InputStream inputStream2 = inputStream.getResourceAsStream("/java/title.txt");
    var title = new String(inputStream2.readAllBytes(), StandardCharsets.UTF_8).trim();
    JOptionPane.showMessageDialog(null, about, title, JOptionPane.INFORMATION_MESSAGE,icon);
  }
}
Get in Touch

Atrowel will be pleased to receive your feedback and suggestions. Those of you who would like to contribute, please send us an email.