03g-1 reflection in java reflection is the ability of a program to manipulate as data something...
DESCRIPTION
03G-3 Example – exploring a type public static void showType(String className) throws ClassNotFoundException { Class thisClass = Class.forName(className); String flavor = thisClass.isInterface() ? "interface" : "class"; System.out.println(flavor + " " + className); Class parent = thisClass.getSuperclass(); if (parent != null) { System.out.println("extends " + parent.getName()); } Class[] interfaces = thisClass.getInterfaces(); for (int i=0; iTRANSCRIPT
03G-1
Reflection In JavaReflection In Java“Reflection is the ability of a program to manipulate as data
something representing the state of the program during its own execution.” [Demers and Malenfant]
• For every loaded class, the JVM maintains an associated Class object
• The Class object “reflects” the class it represents• The primitive Java types are also represented as Class objects
• Instances of the class Class store information about classes• Class name• Inheritance• Interfaces implemented• Methods, members, etc.
• Can look up instances: By name or From an object
03G-2
Accessing the Class objectAccessing the Class objectTo get the Class object for an object mystery:
Class c = mystery.getClass();Or, using the class type:
Class c = mysteryClass.class;Or, using the class name:
Class c = Class.forName(“mysteryClass”);Getting the superclass of MysteryClass:
Class s = c.getSuperclass();Getting the class name:
String s = c.getName();Discovering the interfaces implemented by a class:
Class[] interfaces = c.getInterfaces();Discovering the fields of a class:
Field[] fields = c.getFields();Discovering the methods of a class:
Method[] methods = c.getMethods();
03G-3
Example – exploring a typeExample – exploring a typepublic static void showType(String className)
throws ClassNotFoundException { Class thisClass = Class.forName(className); String flavor = thisClass.isInterface() ?
"interface" : "class"; System.out.println(flavor + " " + className); Class parent = thisClass.getSuperclass(); if (parent != null) { System.out.println("extends " + parent.getName()); } Class[] interfaces = thisClass.getInterfaces(); for (int i=0; i<interfaces.length; ++i) { System.out.println("implements "+ interfaces[i].getName()); }}
03G-4
The OutputThe Output
class java.lang.Object
class java.util.HashMap extends java.util.AbstractMap implements java.util.Map implements java.lang.Cloneable implements java.io.Serializable
class Point extends java.lang.Object
03G-5
Displaying MethodsDisplaying Methodsstatic void showMethods(Object o) { Class c = o.getClass(); Method[] theMethods = c.getMethods(); for (int i = 0; i < theMethods.length; i++) { String methodString = theMethods[i].getName(); System.out.println("Name: " + methodString); System.out.println(" Return Type: " + theMethods[i].getReturnType().getName()); Class[] parameterTypes = theMethods[i].getParameterTypes(); System.out.print(" Parameter Types:"); for (int k = 0; k < parameterTypes.length; k ++) { System.out.print(" " + parameterTypes[k].getName());
}System.out.println();
}}
03G-6
OutputOutputOutput for a call of the form:
Polygon p = new Polygon();showMethods(p);
.
. Name: equals Return Type: boolean Parameter Types: java.lang.ObjectName: getClass Return Type: java.lang.Class Parameter Types:Name: intersects Return Type: boolean Parameter Types: double double double double
03G-7
Main Java reflection ClassesMain Java reflection Classes Class ( java.lang.Class )
Instances of the class Class represent classes and interfaces in a running Java application, every object is represented by a Class object.
Package java.lang.reflect: Member ( java.lang.reflect.Member )
An Interface that reflects identifying information about a single member (a field or a method) or a constructor.
Method ( java.lang.reflect.Method ) Implements Member Interface provides information about, and access to, a single method on a
class or interface. Represents instance methods and class methods ( static )
Field Implements Member Interface provides information about, and dynamic access to, a single field (
also for static fields ) Provides access and modification ( set, get ) methods.
03G-8
Main Java reflection ClassesMain Java reflection Classes Constructor
provides information about, and access to, a single constructor for a class.
PackagePackage objects contain version information about the
implementation and specification of a Java package Modifier
provides static methods and constants to decode class and member access modifiers. The sets of modifiers are represented as integers with distinct bit positions representing different modifiers
03G-9
Reflection API Interface - exampleReflection API Interface - exampleclass Class{
static Class forName(String name);Object newInstance();Field getField(String name);Method getMethod(String name, Class[] paramTypes);
//other methods: getName(), getInterfaces(), // getSuperclass(), getModifiers(), // getFields(), getMethods(), …
}
class Field extends AccessibleObject {Object get(Object obj);void set(Object obj, Object val);//other methods: getType(), getDeclaringClass(), ...
}
03G-10
Exploring the Instantiation HierarchyExploring the Instantiation Hierarchypublic static void traverse(Object o){ for (int n = 0; ; o = o.getClass()) { System.out.println("L"+ ++n + ": " + o +
".getClass() = " + o.getClass()); if (o == o.getClass()) break; }}
public static void main(String[] args){traverse(new Integer(3));}
L1: 3.getClass() = class java.lang.IntegerL2: class java.lang.Integer.getClass() = class java.lang.ClassL3: class java.lang.Class.getClass() = class java.lang.Class
03G-11
Using ArraysUsing Arrays Reflection can be used to create and manipulate
arrays whose size and component type are not known until runtime
public static void testArray(){ Class cls = String.class; int i=10; Object arr = Array.newInstance(cls, i); Array.set(arr, 5, "this is a test"); String s = (String)Array.get(arr, 5); System.out.println(s);}
03G-12
A Java Reflection ExampleA Java Reflection Example Illustrates Four Issues:
Runtime type Information (RTTI) Introspection Invoking Method Objects Dynamic Instantiation
03G-13
Back to our Employee ExampleBack to our Employee Example……Employee
number
level
print()
MonthlyEmployee
print()
HourlyEmployee
print()
Only partial view of theclasses…
public final class MonthlyEmployee extends Employee {public void print() {
System.out.println("I’m a Monthly Employee");}
}
public final class HourlyEmployee extends Employee {public void print() {
System.out.println("I’m a Hourly Employee");}
}
03G-14
Reflection and Dynamic BindingReflection and Dynamic BindingWhat is the output of the following test code:Employee e;e = new MonthlyEmployee();Class c = e.getClass();System.out.println("class of e = " + c.getName());e = new HourlyEmployee();c = e.getClass();System.out.println("class of e = " + c.getName());
class of e = MonthlyEmployeeclass of e = HourlyEmployee
03G-15
SuperClassSuperClassWhat is the output of the following test code:c = c.getSuperclass();System.out.println("base class of e = " + c.getName());c = c.getSuperclass();System.out.println("base of base class of e = "
+ c.getName());
base class of e = Employeebase of base class of e = java.lang.Object
03G-16
Getting and setting fieldsGetting and setting fields
Non public fields are not printed! getDeclaredFields returns all fields declared by the class, but
excludes inherited ones
Field fields[] = c.getFields();for(int i = 0; i < fields.length; i++) {
System.out.print(fields[i].getName() + "= ");System.out.println(fields[i].getInt(e));
}e is an instance of Employee or its subtype
The output produced:number= 111level= 12
Field f = c.getField("level");f.setInt(e,f.getInt(e)+1);
03G-17
Examining ModifiersExamining ModifiersWhat is the output of the following test code:
int m = c.getModifiers(); if (Modifier.isPublic(m))
System.out.println("public"); if (Modifier.isAbstract(m))
System.out.println("abstract"); if (Modifier.isFinal(m))
System.out.println("final");
public final
03G-18
Invoking Method ObjectsInvoking Method Objects• We can ask a method object to invoke the method
it represents• we must provide it with the implicit and explicit
arguments
Employee e = new HourlyEmployee();Class c = e.getClass();Method m = c.getMethod("print", null);m.invoke(e, null);
the output produced:I’m a Hourly Employee
03G-19
Dynamic InstantiationDynamic InstantiationThe universal printer gets the employee type and invokes the print method. class UniversalPrinter {
public void print(String empType) {Class c = Class.forName(empType); Employee emp = (Employee ) c.newInstance();emp.print();
}}-for calling other constructors (with arguments), use the Constructor class - Constructor c = ... - Object newObject = c.newInstance( Object[] initArguments )
What is the output of the following code?
UniversalPrinter p = new UniversalPrinter();String empType;empType = "HourlyEmployee";p.print(empType);empType = "MonthlyEmployee";p.print(empType);
03G-20
Implementing Java ReflectionImplementing Java Reflection At runtime, JVM loads class files and creates
objects representing the classes. Object representing a class has a name (string field), list
of fields (each of type Field) , list of methods…
class Field { String name; Class type; Class clazz; int offset; Object get(Object obj) { if (clazz.isInstance(obj)) { f = ((char*)obj) + offset; return (type.primitive = TRUE ? wrap(f) : (Object)f);
} }}
class Class {String name;Field[] fields;Method[] methods;boolean primitive;
bool isInstance...Object newInstance..}
03G-21
Reflection - WhatReflection - What’’s missings missing Reflection is introspection only
Cant add / modify fields (structure), methods (behavior) Implementation is not available
Program logic is not reflected Major performance impact
Much slower then doing the same operations directly… Complex code
03G-22
Java SerializationJava Serialization the process of converting objects into a linear
stream of bytes Depends on
reflection
public class PersistentTime implements Serializable{ private Date time;
public PersistentTime(){ time = Calendar.getInstance() .getTime(); }
public Date getTime(){return time;}}
String filename = "time.ser";
PersistentTime time = new PersistentTime();FileOutputStream fos = null;ObjectOutputStream out = null; fos = new FileOutputStream(filename);out = new ObjectOutputStream(fos);out.writeObject(time);out.close();