Reflection Field, Method (Part 3)

Each class instances might have its own methods, fields, and constructors, so Class class should address them. in Java reflection, there are separate Types to refer to this need. we have below types which refer to these types in details.

  1. Method
  2. Constructor
  3. Field

below is the same example code that we have written from Part 1 and part 2, but only this time we are going to expand that to cover our concepts.


package com.navid.training.classtester;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
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 {

private String name = "";
int code = 0;

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

}

/**
* just extending this class to express the Class related methods leverage.
*/
private static final class MySubClass extends MyInnerClass implements Runnable {

private String subClassName = "";

public MySubClass(int code) {
super(code);
}

@Override
public void run() {
System.out.println("triggering and runnin this subclass as a thread.");
}
private void method1(){
System.out.println("nothing");
}

public void method2(){
System.out.println("nothing 2");
}

}

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 showModifier(int modifier) {
if (Modifier.isFinal(modifier)) {
System.out.println("its modifier is FINAL - using isFinal()");
}

if (Modifier.isPrivate(modifier)) {
System.out.println("its modifier is PRIVATE");
}
if (Modifier.isProtected(modifier)) {
System.out.println("it's PROTECTED.");
}
if (Modifier.isPublic(modifier)) {
System.out.println("it's public.");
}
if (Modifier.isAbstract(modifier)) {
System.out.println("it's abstract.");
}
if (Modifier.isInterface(modifier)) {
System.out.println("it's interface.");
}
if (Modifier.isNative(modifier)) {
System.out.println("it's NATIVE.");
}
if (Modifier.isStatic(modifier)) {
System.out.println("it's static.");
}
if (Modifier.isStrict(modifier)) {
System.out.println("it's STRICT.");
}
if (Modifier.isSynchronized(modifier)) {
System.out.println("it's Synchronized.");
}
if (Modifier.isVolatile(modifier)) {
System.out.println("it's Volitile.");
}
}

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);

System.out.println("----------PART 2----------");
// Part 2: create an isntance of MySubClass
System.out.println(" ------\n working on SUBCLASSES and Modifier in Class ...");
MySubClass sub = new MySubClass(20);
//its name
Class<?> itself = sub.getClass();
System.out.println("Class itself: " + itself.getName());
//its parent
Class<?> parent = itself.getSuperclass();
System.out.println("SupserClassName: " + parent.getName());
//its interfaces
Class<?>[] interfaces = itself.getInterfaces();
for (Class cc : interfaces) {
System.out.println("Interfaces: " + cc.getName());
}

int modifier = itself.getModifiers();
if (Modifier.isFinal(modifier)) {
System.out.println("its modifier is FINAL - using isFinal()");
}
if ((modifier & Modifier.FINAL) > 0) {
System.out.println("its modifier is FINAL - using BITWISE operation");
}
if (Modifier.isPrivate(modifier)) {
System.out.println("its modifier is PRIVATE");
}
if (Modifier.isProtected(modifier)) {
System.out.println("it's PROTECTED.");
}

System.out.println("----------PART 3 ----------");
// Part 3 : working with Methods and Fields in CLASS
System.out.println("Working with Methods and Fields by Class methods...");

System.out.println("Added one field to subclass and also updating modifier in parent inner class ...");

System.out.println("--------  getDeclaredFields()------------");
Field[] declaredFields_child = sub.getClass().getDeclaredFields();
for (Field f : declaredFields_child) {
System.out.println("DeclaredField: " + f.getName());
showModifier(f.getModifiers());
}
System.out.println("-----------getFields()---------");
// if fields are public won't be shown here.
Field[] fields_child = sub.getClass().getFields();
for (Field f : fields_child) {
System.out.println("Field: " + f.getName());
showModifier(f.getModifiers());
}

System.out.println("--------  getDeclaredMethods()------------");
Method[] declaredMethods = sub.getClass().getDeclaredMethods();
for (Method method : declaredMethods) {
System.out.println("DeclaredField: " + method.toGenericString());
showModifier(method.getModifiers());
}
System.out.println("--------  getMethods()------------");
Method[] methods = sub.getClass().getMethods();
for (Method method : methods) {
System.out.println("Field: " + method.toGenericString());
showModifier(method.getModifiers());
System.out.println("##########");
}

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

}

and its output will be something like …

----------PART 3 ----------
Working with Methods and Fields by Class methods...
Added one field to subclass and also updating modifier in parent inner class ...
--------  getDeclaredFields()------------
DeclaredField: subClassName
its modifier is PRIVATE
-----------getFields()---------
--------  getDeclaredMethods()------------
DeclaredField: public void com.navid.training.classtester.ClassTesting$MySubClass.run()
it's public.
DeclaredField: public void com.navid.training.classtester.ClassTesting$MySubClass.method2()
it's public.
DeclaredField: private void com.navid.training.classtester.ClassTesting$MySubClass.method1()
its modifier is PRIVATE
--------  getMethods()------------
Field: public void com.navid.training.classtester.ClassTesting$MySubClass.run()
it's public.
##########
Field: public void com.navid.training.classtester.ClassTesting$MySubClass.method2()
it's public.
##########
Field: public final void java.lang.Object.wait() throws java.lang.InterruptedException
its modifier is FINAL - using isFinal()
it's public.
##########
Field: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
its modifier is FINAL - using isFinal()
it's public.
##########
Field: public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
its modifier is FINAL - using isFinal()
it's public.
it's NATIVE.
##########
Field: public boolean java.lang.Object.equals(java.lang.Object)
it's public.
##########
Field: public java.lang.String java.lang.Object.toString()
it's public.
##########
Field: public native int java.lang.Object.hashCode()
it's public.
it's NATIVE.
##########
Field: public final native java.lang.Class<?> java.lang.Object.getClass()
its modifier is FINAL - using isFinal()
it's public.
it's NATIVE.
##########
Field: public final native void java.lang.Object.notify()
its modifier is FINAL - using isFinal()
it's public.
it's NATIVE.
##########
Field: public final native void java.lang.Object.notifyAll()
its modifier is FINAL - using isFinal()
it's public.
it's NATIVE.
##########
BUILD SUCCESSFUL (total time: 0 seconds)

in Above code, and its ouput we tried to explain the differences between getDeclaredXXX() and getXXX().

obj.getClass().getDeclaredXXX() – is able to explore and mention all the methods that are not even public, for example we hvae method1 and method2 and only method2 is public, as you can see, getDeclaredMethods() could capture both of them, although getMethods() could only see the public methods.

Hint:

you may notice that in the output, getDelcaredMethods() was able to returning all the public and proivate, protected, etc, however we might not need all of them which came from their parent classes or even from Object class such as: hashCode(), wait(), wait(…), equals(), etc.

to prevent that to trace the hirarchial to all the parents and check all of their methods, you can easily check and make sure we can have all the class itself methods, by below snippet code.


/**
* show only methods of the class
*
* @param c2
*/
public static void showMethodsOfClassObject(Class<?> c2) {

Method[] declaredMethods = c2.getDeclaredMethods();
for (Method method : declaredMethods) {

if (method.getDeclaringClass().equals(c2)) {
System.out.println("Method of this class is: " + method);
}
}
}

output will be something like this:

--------Now only Methods of this class -------
Method of this class is: public void com.navid.training.classtester.ClassTesting$MySubClass.run()
Method of this class is: public void com.navid.training.classtester.ClassTesting$MySubClass.method2()
Method of this class is: private void com.navid.training.classtester.ClassTesting$MySubClass.method1()

 

 

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