Introduction

Using java reflection we can inspect a class, interface, enum, get their structure, methods and fields information at runtime even though class is not accessible at compile time. We can also use reflection to instantiate an object, invoke it’s methods, change field values. Reflection is an API which is used to examine or modify the behavior of methods, classes, interfaces at runtime.

  • The required classes for reflection are provided under java.lang.reflect package.
  • Reflection gives us information about the class to which an object belongs and also the methods of that class which can be executed by using the object.
  • Through reflection we can invoke methods at runtime irrespective of the access specifier used with them.

Reflection can be used to get information about –

  • Class:  The getClass() method is used to get the name of the class to which an object belongs.
  • Constructors: The getConstructors() method is used to get the public constructors of the class to which an object belongs.
  • Methods: The getMethods() method is used to get the public methods of the class to which an objects belongs.

 

Drawbacks

We should not use reflection in normal programming where we already have access to the classes and interfaces because of following drawbacks.

  • Poor Performance – Since java reflection resolve the types dynamically, it involves processing like scanning the classpath to find the class to load, causing slow performance.
  • Security Restrictions – Reflection requires runtime permissions that might not be available for system running under security manager. This can cause you application to fail at runtime because of security manager.
  • Security Issues – Using reflection we can access part of code that we are not supposed to access, for example we can access private fields of a class and change it’s value. This can be a serious security threat and cause your application to behave abnormally.
  • High Maintenance – Reflection code is hard to understand and debug, also any issues with the code can’t be found at comiple time.

 

Example

 

// Program to demonstrate the use of reflection 
class ReflectionExample 
{ 
  // Private field 
  private String s; 

  // Public constructor 
  public ReflectionExample() { 
    s = "Reflection"; 
  } 

  // Public method with no arguments 
  public void method1() { 
    System.out.println("The string is " + s); 
  } 

  // Public method with int as argument 
  public void method2(int n) { 
    System.out.println("The number is " + n); 
  } 

  // Private method 
  private void method3() { 
    System.out.println("Private method invoked"); 
  } 
} 

class Main 
{ 
  public static void main(String args[]) throws Exception 
  { 
    // Creating object whose property is to be checked 
    ReflectionExample obj = new ReflectionExample(); 
    
    // Class object from the class name at compile time
    Class  cls = ReflectionExample.class;

    // Class object from the object using getclass method 
    Class cls = obj.getClass(); 
    System.out.println("The name of class is " + 
              cls.getName()); 

    // Class constructor
    Constructor constructor = cls.getConstructor(); 
    System.out.println("The name of constructor is " + 
              constructor.getName()); 

    System.out.println("The public methods of class are : "); 

    // Methods of the class
    Method[] methods = cls.getMethods(); 

    // Printing method names 
    for (Method method:methods) { 
      System.out.println(method.getName()); 
    }

    // Create object of desired method
    Method methodcall1 = cls.getDeclaredMethod("method2", 
                        int.class); 

    // Invokes the method at runtime 
    methodcall1.invoke(obj, 19); 

    // Creates object of the desired field
    Field field = cls.getDeclaredField("s"); 

    // Access the object irrespective of the access specifier 
    field.setAccessible(true); 
    field.set(obj, "JAVA"); 

    // Creates object of the desired method 
    Method methodcall3 = cls.getDeclaredMethod("method3"); 

    // Allows the object to access the method
    methodcall3.setAccessible(true); 

    // Invokes the method at runtime 
    methodcall3.invoke(obj); 
  } 
}