Reflection Fundamentals (Part 1)

Reflection is an API that provides Type related operations in the Java language. it’s part of JDK and we can group its task into 2 major categories:

  1. Type Checking at RunTime
  2. Getting Access and Executing members and methods at Runtime.

Note: there are times that we don’t know the specific type of objects that we are using. in that case, Reflection is that API that could enable us to verify that.

there is a Class class type that every object instances ; regardless of their types, are referring to it. depending on what type they might have, they have reference to the exact same Class class instance of their type,

for example, if I have an object named:

public Class MyPersonalObject {

   private int codeid = 0;
   private String name= null;
   public MyPersonalObject(int id){ ...}
   public MyPersonalObject(int id,String name){ ...}
   public void method1(){....}
   public void method2(){....}
   public void method3(){....}

}

then you can generate 3 instances of this class. all you can be sure that every individual 3 instances have a reference to an object of Class class that is presenting MyPersonalObject class schema. This Class is very much like a reference to the blueprint of every object instance.

a very common example of using reflection is in JDBC starting point.

Class.forName(""); // then you're loading the JDBC driver.

for example below code will expose what Class.getXxx(), method will work.

package com.navid.training.classtester;

import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author Unknown_
*/
public class ClassTesting {

private static class MyInnerClass {

String name = "";
int code = 0;

public MyInnerClass(int code) {
this.code = code;
}

}

public void doWork(Object obj) {
Class<?> c = obj.getClass();
showClassInfo(c);
}

/**
* extracting and showing the class information.
*
* @param inputClass
*/
public void showClassInfo(Class<?> inputClass) {
System.out.println("SimpleName: " + inputClass.getSimpleName());
System.out.println("CanonicalName: " + inputClass.getCanonicalName());
System.out.println("Name: " + inputClass.getName());
System.out.println("TypeName: " + inputClass.getTypeName());
}

public static void main(String[] args) {

try {

//working with Class methods BASICS.
System.out.println("working with BASICS of CLASS methods.");
MyInnerClass innerClass = new MyInnerClass(12);
// Testing Innerclass instance
ClassTesting tester = new ClassTesting();
tester.doWork(innerClass);

//another test with a JDK Collection util package class
Map m = new HashMap<String, String>();
tester.doWork(m);
// Another test --
System.out.println("Using: Class.forName() -- it needs name and not choronical name!");
System.out.println("This may through \" java.lang.ClassNotFoundException\" - so to call inner classes you need something liek this "
+ "com.navid.training.classtester.ClassTesting$MyInnerClass");
Class<?> c = Class.forName("com.navid.training.classtester.ClassTesting$MyInnerClass");
tester.showClassInfo(c);

//Another test using class operator
System.out.println("Using: type literals for every Object - e.g: MyClass.class");
Class<?> c2 = MyInnerClass.class;
tester.showClassInfo(c2);

} catch (ClassNotFoundException ex) {
Logger.getLogger(ClassTesting.class.getName()).log(Level.SEVERE, null, ex);
}
}

}

and its output will be something like this.

run:
SimpleName: MyInnerClass
CanonicalName: com.navid.training.classtester.ClassTesting.MyInnerClass
Name: com.navid.training.classtester.ClassTesting$MyInnerClass
TypeName: com.navid.training.classtester.ClassTesting$MyInnerClass
SimpleName: HashMap
CanonicalName: java.util.HashMap
Name: java.util.HashMap
TypeName: java.util.HashMap
Using: Class.forName() -- it needs name and not choronical name!
This may through " java.lang.ClassNotFoundException" -
 so to call inner classes you need something like this 
com.navid.training.classtester.ClassTesting$MyInnerClass
SimpleName: MyInnerClass
CanonicalName: com.navid.training.classtester.ClassTesting.MyInnerClass
Name: com.navid.training.classtester.ClassTesting$MyInnerClass
TypeName: com.navid.training.classtester.ClassTesting$MyInnerClass
Using: type literals for every Object - e.g: MyClass.class
SimpleName: MyInnerClass
CanonicalName: com.navid.training.classtester.ClassTesting.MyInnerClass
Name: com.navid.training.classtester.ClassTesting$MyInnerClass
TypeName: com.navid.training.classtester.ClassTesting$MyInnerClass
BUILD SUCCESSFUL (total time: 0 seconds)

In above code, method doWork(Object obj), will do the actual work. you can see how we manipulate and handled the object instance which we have no idea about its type in time of development.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s