Showing posts with label Java Reflexion. Show all posts
Showing posts with label Java Reflexion. Show all posts

Wednesday, October 12, 2011

Invoke methods of an object using reflection


This java code example shows how to invoke methods on an object at runtime without knowing the names of them in advance. This is possible using the reflection API. What we do is to get an instance of the class object of the particular class we want to call methods on and by using that instance we can get the array of Method objects by calling getDeclaredMethods(). We don't actually call the methods of the class instance, instead we have to create an object that we call the methods on by sending it as an argument to the invoke() method. In this example we use an inner class named 'Computer' but of course it could be any object, not necessarily an instance of an inner class. The names of the methods invoked are printed out along with the values that they return.

Package org.best.example;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class Main {
   
    /**
     * Invokes the methods of an object using the Reflection api.
     */
    public void invokeMethodsUsingReflection() {

        //Obtain the Class instance
        Class computerClass = Computer.class;
       
        //Get the methods
        Method[] methods = computerClass.getDeclaredMethods();
       
        //Create the object that we want to invoke the methods on
        Computer computer = new Computer();
       
        //Loop through the methods and invoke them
        for (Method method : methods) {
            Object result;
            try {
                //Call the method. Since none of them takes arguments we just
                //pass an empty array as second parameter.
                result = method.invoke(computer, new Object[0]);
            } catch (IllegalArgumentException ex) {
                ex.printStackTrace();
                return;
            } catch (InvocationTargetException ex) {
                ex.printStackTrace();
                return;
            } catch (IllegalAccessException ex) {
                ex.printStackTrace();
                return;
            }
            System.out.println(method.getName() + ": " + result);
        }
    }
   
   
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new Main().invokeMethodsUsingReflection();
    }
   
   
    class Computer {
       
        private String brand = "DELL";
        private String type = "Laptop";
        private int harddiskSize_GB = 300;
        private boolean AntiVirusInstalled = true;

        public String getBrand() {
            return brand;
        }

        public String getType() {
            return type;
        }

        public int getHarddiskSize_GB() {
            return harddiskSize_GB;
        }

        public boolean isAntiVirusInstalled() {
            return AntiVirusInstalled;
        }
    }
}
The output of the code above is:

getBrand: DELL
getHarddiskSize_GB: 300
isAntiVirusInstalled: true
getType: Laptop

Tuesday, October 11, 2011

Instantiate unknown class at runtime and call the object's methods


This java code example shows how to create an object at runtime for which the name of the class is not know at compile time.We use the forName() method to load the class and then use the newInstance() method to create the object. Then we use reflection to get the methods of the class and invoke them. The class we are instantiating is called MyClass (see further below) and we assume that the methods we are interested in starts with the string 'say' (we don't want to call all the methods inherited from java.lang.Object).

package org.best.example;

import java.lang.reflect.Method;


public class Main {

    public void loadClass() {
        try {

            Class myclass = Class.forName(getClassName());

            //Use reflection to list methods and invoke them
            Method[] methods = myclass.getMethods();
            Object object = myclass.newInstance();
           
            for (int i = 0; i < methods.length; i++) {
                if (methods[i].getName().startsWith("say")) {
                    System.out.println(methods[i].invoke(object));
                }
               
            }
           
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
   
    private String getClassName() {
       
        //Do appropriate stuff here to find out the classname
       
        return "
org.best.example.MyClass";
    }

    public static void main(String[] args) {
        new Main().loadClass();
    }
}

MyClass:

package org.best.example;


public class MyClass {
   
    public String sayHello() {
       
        return "Hello";
    }
   
    public String sayGoodbye() {
       
        return "Goodbye";
    }

}


The output from the example will be:
Hello
Goodbye

Monday, October 10, 2011

List methods of a class using Reflection


In this example we use the Reflection api to obtain the methods of a particular class called Person, which is an inner class. First we need to get the Class object and we do so by calling 'Person.class'. Once we have the Class object we can use it to call the getDeclaredMethods() method which will return an array of type Method.To find out the names of the methods that the Person class contains we simply loop through the array and call getName() for each Method object.

Package org.best.example;
import java.lang.reflect.Method;


public class Main {
   
    /**
     * Lists the methods of a class using the Reflection api.
     */
    public void listMethodsUsingReflection() {

        //Obtain the Class instance
        Class personClass = Person.class;
       
        //Get the methods
        Method[] methods = personClass.getDeclaredMethods();
       
        //Loop through the methods and print out their names
        for (Method method : methods) {
            System.out.println(method.getName());
        }
    }
   
   
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new Main().listMethodsUsingReflection();
    }
   
   
    class Person {

private String firstname;
        private String lastname;
        private String age;

        public String getFirstname() {
            return firstname;
        }

        public void setFirstname(String firstname) {
            this.firstname = firstname;
        }

        public String getLastname() {
            return lastname;
        }

        public void setLastname(String lastname) {
            this.lastname = lastname;
        }

        public String getAge() {
            return age;
        }

        public void setAge(String age) {
            this.age = age;
        }
    }
}

If you run the example code above the output will be:

getFirstname
setFirstname
getLastname
setLastname
getAge
setAge

Tuesday, May 24, 2011

How to Play with access modifiers at runtime

There are situations where you want to access private member variables . An example of this is trying to access the socket fd (descriptor) from the Socket implementation in Java for doing some jni operations on it. The file descriptor is stored as a private member variable in the Socket class, and can be accessed using this example. 

package org.best.example;

import java.lang.reflect.Field;

/**
* Class with the private variable
*/
class Hmmm
{
    //private variable only accessible from this class
    private int iWannaGoPublic=20; 
}


/**
* Class with code to access the private variable in Hmmm
*/
public class ChangeAccessExample
{
    public static void main(String[] args) throws Exception
    {
        Hmmm hmmmInstance=new Hmmm();
        Class hmmClass = hmmmInstance.getClass();
        Field f = hmmClass.getDeclaredField("iWannaGoPublic");
        f.setAccessible(true); //Make the variable accessible
        
        Object implVal = f.get(hmmmInstance);
        int fd=((Integer) implVal).intValue();
        
        System.out.println("Value of the private var is" + fd);
        //Let me restore the access before someone finds out :-)
        f.setAccessible(false);
    }
}