Friday, June 8, 2012

Reflection and VarArgs in Java

Dear reader,

This article is an extention of my earlier article "Reflection in Java", which can be seen at below link:
http://deepakmodi2006.blogspot.in/2012/04/reflection-in-java.html

Here I am writing about:
1) Complete example and use of "Vararg" (Variable Arguments Array) in Java. "Vararg" is used to hold
   an array of objects with un-defined size. Please see the example below, I have made it very very simple.
2) Reflection and use in calling Setter, Getter method in Java. This I have faced in my application as
   using reflection we had to set some parameters and use the same object to fetch the data using Getter.
3) A more generic program to display all setter and getter methods of a class.
   
==============================================================          
//VarArg example with output
public class VarArgsExample {  
    public static void main(String[] args) throws Exception {  
        String[] greetings = { "Hello", "Deepak" };  

        //No warning  
        Object[] objects = greetings;  

        //No warning  
        arrayTest(greetings);  

        //No warning  
        varargTest(objects);

        //No warning
        varargTest(new Object[]{}); 

        //Warning: The argument of type String[] should explicitly be cast to Object[] for the 
        //invocation of the varargs method varargTest(Object...)   
        varargTest(greetings);    

        //No warning
        varargTest();
        
        //Warning: The argument of type null should explicitly be cast to Object[] for the 
        //invocation of the varargs method varargTest(Object...)
        varargTest(null);
    }  

    public static Object[] arrayTest(Object[] p) {  
        return p;  
    }  
    public static Object[] varargTest(Object... p) {  
        System.out.println(p.length);
        return p;  
    }  
}  

//Output:
2
0
2
0
Exception in thread "main" java.lang.NullPointerException
    at VarArgsExample.varargTest(VarArgsExample.java:33)
    at VarArgsExample.main(VarArgsExample.java:26)
==============================================================  

//Reflection and Setter/Getter method:
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class SetterGetterReflection {
    private String firstName;
    private String middleName;
    private String lastName;

    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getMiddleName() {
        return middleName;
    }
    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    //Main method to execute the program
    public static void main(String[] args) throws Exception {
        SetterGetterReflection myObject=new SetterGetterReflection();          

        Class myclass = myObject.getClass();

        //Invoking setter method using reflection
        Method setterMethod = myclass.getMethod("setFirstName", java.lang.String.class);
        setterMethod.invoke(myObject, new Object[] {"Deepak"});

        setterMethod = myclass.getMethod("setLastName", java.lang.String.class);
        setterMethod.invoke(myObject, new Object[] {"Modi"});
        
        //Values are set using Reflection setter method
        System.out.println("FirstName: "+myObject.getFirstName());
        System.out.println("LastName: "+myObject.getLastName());
        
        //Now fetching getter method
        Method getterMethod = myclass.getMethod("getFirstName",  new Class[]{});
        String fName = getterMethod.invoke((Object) myObject, new Object[]{}).toString();
        
        getterMethod = myclass.getMethod("getLastName",  new Class[]{});
        String lName = getterMethod.invoke((Object) myObject, new Object[]{}).toString();
        System.out.println("FirstName: "+fName+", LastName: "+lName);
        
        
        Field fields[]=myObject.getClass().getDeclaredFields();  //All fields including private
        //Field fields[]=myObject.getClass().getFields();  //Only public declared fields
        String fieldNames[]=new String[fields.length];
        
        for(int i=0;i<fields.length;i++){
            fieldNames[i]=fields[i].getName();
        }

        for(String f:fieldNames){
            System.out.println("FieldName: "+f);
        }
        
        SetterGetterReflection myAnotherObject=new SetterGetterReflection();          
        String setterMethodNames[]=myAnotherObject.getAllSetterMethodNames(fieldNames);
        for(String s:setterMethodNames){
            System.out.println("Setter Method name: "+s);
            //Now use reflection to invoke methods
        }
                 
        String getterMethodNames[]=myAnotherObject.getAllGetterMethodNames(fieldNames);
        for(String s:getterMethodNames){
            System.out.println("Getter Method name: "+s);
            //Now use reflection to invoke methods
        }
        
    }
    public String[] getAllSetterMethodNames(String[] fieldNames){
        String mNames[]=new String[fieldNames.length];
        
        for(int i=0;i<fieldNames.length;i++) {
            String mName=fieldNames[i];
            mName=mName.replace(mName.charAt(0), Character.toUpperCase(mName.charAt(0)));
            mNames[i]="set"+mName;
        }
        return mNames;
    }
    public String[] getAllGetterMethodNames(String[] fieldNames){
        String mNames[]=new String[fieldNames.length];
        
        for(int i=0;i<fieldNames.length;i++) {
            String mName=fieldNames[i];
            mName=mName.replace(mName.charAt(0), Character.toUpperCase(mName.charAt(0)));
            mNames[i]="get"+mName;
        }
        return mNames;
    }
}

//Output:
FirstName: Deepak
LastName: Modi
FirstName: Deepak, LastName: Modi
FieldName: firstName
FieldName: middleName
FieldName: lastName
Setter Method name: setFirstName
Setter Method name: setMiddleNaMe
Setter Method name: setLastName
Getter Method name: getFirstName
Getter Method name: getMiddleNaMe
Getter Method name: getLastName

==============================================================  
//Program to display setter and getter methods of a class:
import java.lang.reflect.Method;

public class FindSetterGetter {
    private String firstName;
    private String middleName;
    private String lastName;

    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getMiddleName() {
        return middleName;
    }
    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public static void main(String[] args) {
        printGettersSetters(FindSetterGetter.class);
    }
    public static void printGettersSetters(Class aClass){
        Method[] methods = aClass.getMethods();

        for(Method method : methods){
            if(isGetter(method)) System.out.println("getter: " + method);
            if(isSetter(method)) System.out.println("setter: " + method);
        }
    }

    public static boolean isGetter(Method method){
        if(!method.getName().startsWith("get"))      return false;
        if(method.getParameterTypes().length != 0)   return false;  
        if(void.class.equals(method.getReturnType())) return false;
        return true;
    }

    public static boolean isSetter(Method method){
        if(!method.getName().startsWith("set")) return false;
        if(method.getParameterTypes().length != 1) return false;
        return true;
    }
}

//Output:
getter: public java.lang.String FindSetterGetter.getFirstName()
setter: public void FindSetterGetter.setFirstName(java.lang.String)
getter: public java.lang.String FindSetterGetter.getMiddleName()
setter: public void FindSetterGetter.setMiddleName(java.lang.String)
getter: public java.lang.String FindSetterGetter.getLastName()
setter: public void FindSetterGetter.setLastName(java.lang.String)
getter: public final native java.lang.Class java.lang.Object.getClass()

==============================================================  

No comments:

Post a Comment