Working with Java Reflection

Java reflection gives flexibility of controlling java application's behavior runtime. This tutorial explains using java reflection to load, instantiate and access member dynamically.
Some simple and straight forward steps to use reflection are


1. Load class and get reference to Class Object [ using default class loader or custom one ]get required class properties using Class Object such as constructor, methods, fields etc

2. Instantiate class either using specific constructor or default one.

3. Invoke methods using object reference.


Here , class MyCar is being accessed using reflection by TestRefelction class.

MyCar

package reflectionproject;

public class MyCar {
/**
* private memebrs
*/
private String modelName;
private String color;
public static String parkingSlot;

/**
* default constructor
*/
public MyCar() {
}

public MyCar(String modelName, String color){
this.modelName = modelName;
this.color = color;
}

public String getColor(){
return color;
}


public void changeColor(String color){
this.color = color;
}

public Engine getEngineType(){
return Engine.petrolEngine;
}

/**
* Static Inner class
*/
public static class Engine{
private String engineType = null;

public Engine(String type){
this.engineType = type;
}

public static Engine dieselEngine = new Engine("diesel");
public static Engine petrolEngine = new Engine("petrol");
}
}

TestReflcetion :

package reflectionproject.test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import reflectionproject.MyCar.Engine;

public class TestReflcetion {
public TestReflcetion() {
}

public static void main(String[] args){
try{
//Load class
Class cls = Class.forName("reflectionproject.MyCar");

//get Constructor
Constructor con = cls.getConstructor(new Class[]{String.class, String.class});

//create instance using constructor
Object obj = con.newInstance(new Object[]{"S-Class", "White"});
System.out.println("Instatiated MyCar Object");

//get instance method info
Method getColorMtd = cls.getMethod("getColor",null);

//call method
String color = (String)getColorMtd.invoke(obj, new Object[]{});
System.out.println("Color is " + color);

//access static field
Field f = cls.getField("parkingSlot");

//set field value, passing null because it is static field
f.set(null,"01");

//get field value, passing null because it is static field
System.out.println("Allocated Parking slot is "+ f.get(null));

//access instance method
Method setColorMtd = cls.getMethod("changeColor", new Class[]{String.class});

//call setColor method
setColorMtd.invoke(obj, new Object[]{"Red"});

//accessing static inner class,
Class engineCls = Class.forName("reflectionproject.MyCar$Engine");

Method getEngineMtd = cls.getMethod("getEngineType",null);
Object engObj = getEngineMtd.invoke(obj,null);

Object petrolEngineType = engineCls.getField("petrolEngine").get(null);

if(engObj == petrolEngineType){
System.out.println("Engine type is Petrol engine");
}

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


In this example, MyCar is loaded by usingClass.forName("reflectionproject.MyCar"). This statement returns object of type Class. This Class object has complete information about MyCar class, such as no of methods, method signature, no of constructors etc. In next step information about Constructor with two String parameters is being retrieved using Class object. This returns object of type Constructor. Using this constructor object an new object of type MyCar is instantiated.

Similarly every method and fields are accessed. Here one important point has to be noticed, that is name for inner class. Normally refereing static inner class is ParentClass.InnerClass, in our case MyCar.Engine. But at run time it is referred by MyCar$Engine.Thats why while loading inner class"reflectionproject.MyCar$Engine" is being passed to Class.forName.

Comments

  1. Hello,

    maybe you'll find this project useful for dealing with reflection.

    http://projetos.vidageek.net/mirror/mirror/

    Regards,

    ReplyDelete

Post a Comment

Popular posts from this blog

State Design Pattern by Example

Eclipse command framework core expression: Property tester

Composite Design Pattern by example