160 likes | 183 Views
Reflection In Java. For every loaded class, the Java Runtime Environment (JRE) maintains an associated Class object The Class object “ reflects ” the class it represents The primitive Java types are also represented as Class objects Reflection can be used to:
E N D
Reflection In Java • For every loaded class, the Java Runtime Environment (JRE) maintains an associated Class object • The Class object “reflects” the class it represents • The primitive Java types are also represented as Class objects • Reflection can be used to: • Determine the class of an object. • Get information about a class's modifiers, fields, methods, interfaces, constructors, and superclasses. • Create an instance of a class whose name is not known until runtime. • Get and set the value of an object's field. • Invoke a method on an object.
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. • 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.
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
Accessing the Class object To get the Class object for an object mystery: Class c = mystery.getClass(); 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();
Example 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); String returnString = theMethods[i].getReturnType().getName(); System.out.println(" Return Type: " + returnString); Class[] parameterTypes = theMethods[i].getParameterTypes(); System.out.print(" Parameter Types:"); for (int k = 0; k < parameterTypes.length; k ++) { String parameterString = parameterTypes[k].getName(); System.out.print(" " + parameterString); } System.out.println(); } }
Example – Cont. 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 double double double . .
A Java Reflection Example • Illustrates Four Issues: • Runtime type Information (RTTI) • Introspection • Invoking Method Objects • Dynamic Instantiation
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"); } }
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
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
Non public fields are not printed! Getting all fields 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)); } The output produced: number= 111 level= 12 e is an instance of Employee or its subtype !
Setting a Field Let’s promote an employee… Field fields[] = c.getFields(); for(int i = 0; i < fields.length; i++) { if(fields[i].getName() == “Level”) fields[i].setInt(e, (fields[i].getInt(e))++); }
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
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
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 = new UniversalPrinter(); String empType; empType = “HourlyEmployee"; p.print(empType); empType = “MonthlyEmployee"; p.print(empType);
Reflection - What’s missing • Reflection is ‘read only’ • Cant add / modify fields, methods • Non public members (fields, methods) are not accessible • Implementation is not available • Program logic is not reflected • Major performance impact • Much slower then doing the same operations directly… • Complex code