Saturday, June 8, 2013

Reflection in Java (and a little Python)

toString(), iterates through every attributes in a Class


public class Formatter {
    public static String toString(Object aObject) {
        StringBuilder result = new StringBuilder();
        String newLine = System.getProperty("line.separator");
        
        result.append( aObject.getClass().getName() );
        result.append( " Object {" );
        result.append(newLine);
        
        //determine fields declared in aObject class only (no fields of superclass)
        Field[] fields = aObject.getClass().getDeclaredFields();
        
        //print field names paired with their values
        for ( Field field : fields  ) {
            result.append("  ");
            try {
                field.setAccessible(true);
                result.append( field.getName() );
                result.append(": ");
                //requires access to private field:
                result.append( field.get(aObject) );
            } catch ( IllegalAccessException ex ) {
                System.out.println(ex);
            }
            result.append(newLine);
        }
        result.append("}");
        
        return result.toString();
    }

}

Invoke Method

        Class[] setterParameterTypes = new Class[1];
        setterParameterTypes[0] = type;
        Method getter = obj.getClass().getMethod(getterName, null);
        Method setter = obj.getClass().getMethod(setterName, setterParameterTypes);
        
        Object a = getter.invoke(obj, null);
        setter.invoke(obj, a);  
        Book aBook = new Book();
        Class aClass = aBook.getClass();
        Class [] param = {String.class};
        Method method = aBook.getClass().getMethod("setCallNo", param);
        method.invoke(aBook, "this is a copy number");
        method = aBook.getClass().getMethod("getCallNo", null);
        System.out.println(method.invoke(aBook, null));
        System.out.println(aBook.toString());

reflection-oriented program

consider an application that uses two different classes X and Y interchangeably to perform similar operations. Without reflection-oriented programming, the application might be hard-coded to call method names of class X and class Y. However, using the reflection-oriented programming paradigm, the application could be designed and written to utilize reflection in order to invoke methods in classes X and Y without hard-coding method names.

// Without reflection
new Foo().hello();
 
// With reflection
Class<?> fooClass = Class.forName("Foo");
fooClass.getMethod("hello").invoke(fooClass.newInstance());

The following is an example in Python:
# without reflection
obj = Foo()
obj.hello()
 
# with reflection
class_name = "Foo"
method = "hello"
obj = globals()[class_name]()
getattr(obj, method)()
 
# with eval
eval("Foo().hello()")

No comments:

Post a Comment