1 / 22

Reflection In Java

Reflection 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

scotttorres
Download Presentation

Reflection In Java

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Reflection 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

  2. Accessing the Class object To 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();

  3. Example – exploring a type publicstaticvoid 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()); } }

  4. The 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

  5. Displaying Methods staticvoid 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(); } }

  6. Output Output for a call of the form: Polygon p = new Polygon(); showMethods(p); . . Name: equals Return Type: boolean Parameter Types: java.lang.Object Name: getClass Return Type: java.lang.Class Parameter Types: Name: intersects Return Type: boolean Parameter Types: double doubledoubledouble

  7. Main 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.

  8. Main Java reflection Classes • Constructor • provides information about, and access to, a single constructor for a class. • Package • Package 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

  9. Reflection API Interface - example class 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(), ... }

  10. Exploring the Instantiation Hierarchy publicstaticvoidmain(String[] args){ traverse(new Integer(3)); } L1: 3.getClass() = class java.lang.Integer L2: class java.lang.Integer.getClass() = class java.lang.Class L3: class java.lang.Class.getClass() = class java.lang.Class publicstaticvoid traverse(Object o){ for (int n = 0; ; o = o.getClass()) { System.out.println("L"+ ++n + ": " + o + ".getClass() = " + o.getClass()); if (o == o.getClass()) break; } }

  11. Using Arrays publicstaticvoidtestArray(){ Class cls = String.class; inti=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); } Reflection can be used to create and manipulate arrays whose size and component type are not known until runtime

  12. A Java Reflection Example • Illustrates Four Issues: • Runtime type Information (RTTI) • Introspection • Invoking Method Objects • Dynamic Instantiation

  13. Back to our Employee Example… Employee number level print() Only partial view of the classes… HourlyEmployee print() MonthlyEmployee print() public final class MonthlyEmployee extends Employee { publicvoid print() { System.out.println("I’m a Monthly Employee"); } } public final class HourlyEmployee extends Employee { publicvoid print() { System.out.println("I’m a Hourly Employee"); } }

  14. Reflection and Dynamic Binding What 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 = MonthlyEmployee class of e = HourlyEmployee

  15. SuperClass What 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 = Employee base of base class of e = java.lang.Object

  16. Getting 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(inti = 0; i < fields.length; i++) { System.out.print(fields[i].getName() + "= "); System.out.println(fields[i].getInt(e)); } The output produced: number= 111 level= 12 e is an instance of Employee or its subtype Field f = c.getField("level"); f.setInt(e,f.getInt(e)+1);

  17. Examining Modifiers What 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

  18. Invoking 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

  19. Dynamic Instantiation The universal printer gets the employee type and invokes the print method. class UniversalPrinter { publicvoid 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 = newUniversalPrinter(); String empType; empType = "HourlyEmployee"; p.print(empType); empType = "MonthlyEmployee"; p.print(empType);

  20. Implementing Java Reflection class Class { String name; Field[] fields; Method[] methods;boolean primitive; boolisInstance... Object newInstance.. } 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); } }} • 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…

  21. Reflection - What’s 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

  22. Java Serialization publicclassPersistentTimeimplementsSerializable{private Date time; publicPersistentTime(){ time = Calendar.getInstance() .getTime(); } public Date getTime(){return time;}} String filename = "time.ser"; PersistentTime time = newPersistentTime();FileOutputStreamfos = null;ObjectOutputStream out = null;fos = newFileOutputStream(filename);out = newObjectOutputStream(fos);out.writeObject(time);out.close(); • the process of converting objects into a linear stream of bytes • Depends on reflection

More Related