Reflection API in java

No alt text provided for this image

What is Reflection in Programming?

•It is a language's ability to inspect and dynamically all classes, methods, attributes, etc. at runtime.

•Reflection makes it possible to inspect classes, interfaces, fields and methods at runtime, without knowing the names of the classes, methods etc. at compile time.

•In Java, the process of analyzing and modifying all the capabilities of a class at run time is called Reflection.


No alt text provided for this image

What is reflection in java?

 Supporting unknown classes is difficult and even harder to design for in a program, for solving this issue Reflection API came in to picture.

Basically,The Reflection API consists two elements 

1.Objects 

  Objects used for representing various parts in a class file.

2.Security Safe Guards 

  Extracting those objects in a safe and Secure way.

 The first component of the Reflection API is -> The mechanism used to fetch information about a class.

 This mechanism is built into the class named Class

A Class object is an instance of class(java.lang.Class)

About Class Object?

Special Class is the universal type for the meta information that describes objects within the Java system. Class loaders in the Java system return objects of type Class.

Before you can do any inspection on a class you need to obtain its java.lang.Class object. All types in Java including the primitive types (int, long, float etc.) including arrays have an associated Class object.

How to Obtain Class object for any Object:

1.If you know the name of the class at compile time you can obtain a Class object like this:

Class classObject=Myclass.class;//Any class        

2.If you don't know the Class name at compile time, but have the class name as a string at run time, you can do like this:

String className = ... //obtain class name as string at runtime 

Class class = Class.forName(className);        

When using the Class.forName() method you must supply the fully qualified class name. That is the class name including all package names. For instance, if MyObject is located in package com.srinu.test then the fully qualified class name is com.srinu.test.MyObject

The Class.forName() method may throw a ClassNotFoundException if the class cannot be found on the classpath at runtime.

Some Useful methods in Class class

public final native Class<?> getClass()
public T newInstance()
public Constructor<T> getConstructor(Class<?>...parameterTypes) 
public Constructor<?>[] getConstructors()
public Constructor<?>[] getDeclaredConstructors()
public Method getMethod(String name, Class<?>...parameterTypes)
public Method[] getMethods()
public Method[] getDeclaredMethods()
public Field getField(String name)
public Field[] getFields()
public Field[] getDeclaredFields() 
public native Class<? super T> getSuperclass()
public Class<?>[] getInterfaces()
public Class<?>[] getDeclaredClasses()        

I will discuss more this methods in corresponding sections

Getting Any class name

From a Class object, you can obtain its name in two Ways By Using the Below Methods.

1. public String getName()

            Returns the fully qualified name of the entity (class, interface, array class, primitive type, or void) represented by this Class object, as a String.

           If this class object represents a class of arrays, then the internal form of the name consists of the name of the element type preceded by one or more '[' characters representing the depth of the array nesting.

String.class.getName()
     returns "java.lang.String“

 byte.class.getName()
     returns "byte“

 (new Object[3]).getClass().getName()
     returns "[Ljava.lang.Object;“

 (new int[3][4][5][6][7][8][9]).getClass().getName()
     returns "[[[[[[[I"        

public String getSimpleName()

    Returns the simple name of the underlying class. Without package name.

Class<?> classObj=MyClass.class;
      System.out.println(classObj.getName());
      System.out.println(classObj.getSimpleName());
OutPut:

com.pratice.MyClass

MyClass        

Modifiers class

The Modifier class provides static methods and constants to decode class and member access modifiers. modifiers are the keywords "public", "private", "static" etc.

Some Methods

    Modifier.isAbstract(int modifiers)
    Modifier.isFinal(int modifiers)
    Modifier.isInterface(int modifiers)
    Modifier.isPrivate(int modifiers)
    Modifier.isProtected(int modifiers)
    Modifier.isPublic(int modifiers)
    Modifier.isStatic(int modifiers)
    Modifier.isStrict(int modifiers)
    Modifier.isSynchronized(int modifiers)
    Modifier.toString(int mod)//Return a string describing the access //modifier flags in the specified modifier        

Example

public final class MyClass{}

  Class<?> classObj = MyClass.class;
  int mod = classObj.getModifiers();
  System.out.println(Modifier.isPublic(mod));
  System.out.println(Modifier.toString(mod));

OutPut:
true
public final        

Package class

  Package objects contain version information about the implementation and specification of a Java package.

Some Use full Methods

  getName()
  getImplementationTitle()
  getSpecificationTitle()
  getSpecificationVersion()
  getSpecificationVersion()

Example:
Package packageInfo=classObj.getPackage();
System.out.println(packageInfo.getName());//prints the pakage name        

Superclass and Interfaces 

   getInterfaces();

     It will return an array of Class Objects because a class can implement many interfaces, only directly declared interfaces will be returned. The returned array contains interfaces class objects, in reflection interfaces are also treated as Class type objects.

getSuperclass()

It will return only one object because java supports single class inheritance through classes 

A superclass class object is a Class object like any other, so you can continue doing class reflection on that too.

Class<?> classObj = MyClass.class;
  Class<?>[] interfacess = classObj.getInterfaces();

  for (Class<?> c : interfacess) {
  System.out.println(c.getName());
  }
  Class<?> superClass = classObj.getSuperclass();
  System.out.println(superClass.getName());        

Java Reflection - Constructor

Constructor provides information about, and access to, a single constructor for a class. The constructor permits widening conversions to occur when matching the actual parameters to newInstance() with the underlying constructor's formal parameters.

Some useful methods:

        getConstructors()
        getDeclaredConstructors()
        getConstructor(Class<?>... parameterTypes)
        getParameterTypes()
        newInstance(Object ... initargs)        

Obtaining Constructor Objects

•getConstructors()

       Returns an array containing Constructor objects reflecting all the public constructors of the class represented by this Class object.

•getDeclaredConstructors()

same as above method but it contains all the constructors ( private, public, protected etc)

•getConstructor(Class<?>... parameterTypes)

      Returns a Constructor object that reflects the specified public constructor of the class represented by this Class object.

Class<?> myCLass=MyClass.class;
Constructor<?> []constructors=myCLass.getDeclaredConstructors();        

Constructor Parameters

•getParameterTypes()     

 Returns an array of code Class objects that represent the formal parameter types, in declaration order.

Constructor<?> constructor=//obtain constructor object
Class[] parameterTypes = constructor.getParameterTypes();        

Instantiating Objects using Constructor Object

newInstance(Object ... initargs)

  Uses the constructor represented by this Constructor object to create and initialize a new instance of the constructor's declaring class , with the specified initialization parameters.

Class<?> myCLass = MyClass.class;
Constructor<?> constructorObj = myCLass.getConstructor();
MyClass myObject = (MyClass) constructorObj.newInstance();        

Java Reflection Field

A Field provides information about, and dynamic access to, a single field of a class or an interface. The reflected field may be a class (static) field or an instance field.

Obtaining Field Objects

We can obtain field object from Class object

Class<?> myCLass = MyClass.class;
Field[] fields = myCLass.getFields();        

A Field provides information about, and dynamic access to, a

single field of a class or an interface. The reflected field may be a class (static) field or an instance field.

Some Use full methods

getFields()
getName()
isEnumConstant()
getType()        

•getFields()

Returns an array containing Field objects reflecting all the public fields of the class or interface.

Class<?> myCLass = MyClass.class;

Field[] fields = myCLass.getFields();        

•getName()

Returns the name of the field represented by Field object.

Field[] fields = myCLass.getFields();

String fieldName=fields[0].getName();        

•isEnumConstant()

Returns true if this field represents an element of an enumerated type else it returns false.

Field field=//Obtain field object 

field.isEnumConstant();        

•getType()

Returns a Class object that identifies the declared type for the field represented by Field object.

Object fieldType = field.getType();        

Java Reflection - Method

  A java.lang.reflect.Method provides information about, and access to, a single method on a class or interface. The reflected method may be a class method or an instance method (including an abstract method).

Obtaining Method Objects

We can obtain Method object from Class object

Class<?> myCLass = MyClass.class;
 Method[] methods = myCLass.getMethods();        

•The Method[] contains array of Method objects representing the public methods of this class

•If you know the parameter of method you want to access you can directly access particular method rather than accessing all methods

  by using getMethod(“method name”, parametors ) in Class class

     public Method getMethod(String name, Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException {…}        

Method parameters & Return Types  

Bu using java reflection it is possible to inspect the method parameters and return type

 Method method=//Obtain mrthod object
 Class[] parameterTypes = method.getParameterTypes();        

Above method will returns the all the parameters of an particular Method.

Method method = //Obtain method object
Class returnType = method.getReturnType();         

Returns the return type of an Method

Accessing Private Members

Personally I think this is most interesting feature in java reflection . As per common beleaf "accessing private member's of an class in out side of an private member class is not possible" but this is not true . by using java reflection we can access all members of an class including private members. There's a long-standing debate on whether accessing private members is a good habit but I am here for only discuss this feature .

Accessing private Fields

To access a private field we need to the Class.getDeclaredField(“field Name”) call or Class.getDeclaredFields() method. The methods Class.getField(String name) and Class.getFields()methods only return public fields by using this methods we can’t access private Fields.

Here I am taking simple class with single private field and below code for accessing this field using java reflection API

public class PrivateFieldClass {
private String privateData="This Is Private Field Data";
}



PrivateFieldClass privateFieldClass = new PrivateFieldClass();
Field field = privateFieldClass.getClass().
                      getDeclaredField("privateData"); // NoSuchFieldException
field.setAccessible(true);//Making Field accessible
String iWantThis = (String)
                       field.get(privateFieldClass); // IllegalAccessException
System.out.println("privateFieldValue = " + iWantThis);

•O/P
privateFieldValue = This Is Private Field Data        

Accessing private Methods

To access a private method we need to call the getDeclaredMethod(String name, Class<?>... parameterTypes) or Class.getDeclaredMethods() method. The methods Class.getMethod(String name, Class<?>... parameterTypes) and Class.getMethods() methods only return public methods by using this methods we can’t access private Methods.

Here I am taking simple class with single private Method and below code for accessing this Method using java reflection API


public class PrivateMethodClass {
    private String doSomething(){
      return "This is private Method"; 
    }   
}

PrivateMethodClass privateMethodClass = new PrivateMethodClass();
Method method = privateMethodClass.getClass().
                      getDeclaredMethod("doSomething"); // NoSuchMethodException
method.setAccessible(true);//Making Method accessible
String retunValue = (String) method.
                      invoke(privateMethodClass, null); // IllegalAccessException
System.out.println("privateMethodValue = " + retunValue);

O/P
privateMethodValue = This is private Method        

Thanks for reading suggestions are most welcome

Have a Good Day :)



To view or add a comment, sign in

More articles by Srinivas Nangana

  • Java 8 Lambdas&Functional Interface.

    Since the release of Java 1.0, Java has won a large following of programmers who are active users.

  • Project Release Process in Real Time

    Product Development Life Cycle (PDLC)/Software Development Life Cycle (SDLC) I am assuming it was java based JEE…

Insights from the community

Others also viewed

Explore topics