Advanced Java Programming Lecture 5 Reflection dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl http://wbieniec.kis.p.lodz.pl References: http://docs.oracle.com/javase/tutorial/reflect/index.html http://en.wikipedia.org/wiki/Reflection_(computer_science) Reflection Wikipedia: In computer science, reflection is the ability of a computer program to examine and modify the structure and behavior of an object at runtime - its values, meta-data, properties and functions. Looking into the structure of the objects is called type introspection. Reflection is most commonly used in high-level virtual machine programming languages, scripting languages but also statically typed programming languages In Java: Provides a rich and advanced set of tools for writing programs which dynamically can manage Java code Is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the JVM This mechanism is often used in JavaBeans Reflection usage ● Analysis of class properties at application runtime ● Inspection of objects at application runtime. For example, to write a toString method that works in all classes ● ● Implementation of generic code which manipulates arrays The usage of Method objects that work like pointers to functions in C++ Reflection properties Reflection is an advanced feature and should be used only by developers who have a strong knowledge ofJava. With this in mind, reflection is a powerful technique and can enable applications to perform operations which would otherwise be impossible. Extensibility Features We may use external, user-defined classes by creating instances of extensibility objects using their fully-qualified names. Class Browsers and Visual Development Environments A class browser needs to be able to enumerate the members of classes. Visual development environments can benefit from making use of type information available in reflection to help the developer. Debuggers and Test Tools Debuggers need to be able to examine private members on classes. Test sequences may use reflection to systematically call a discoverable set of APIs defined on a class, to insure a high level of code coverage in a test suite. How to obtain java.lang.Class object? All types in Java including the primitive types (int, float etc.) have an associated Class object. They can be obtained in a few ways: If an instance of an object is available, then by invoking object.getClass(): Class c = myObject.getClass(); If fully-qualified class name is available: Class c = Class.forName("com.bull.MyService"); If there is no instance, but the type is available: int test; Class c = test.getClass(); errorClass c = test.class; // compile-time // correct It should be noted that a Class object, in fact, refers to a type, which may or may not be a class. For example, an int is not a class, but int.class is an object of class Class Basic operation on Class object JVM for every type, supports a unique Class object, therefore, to compare them operator == can be used if (e.getClass() == Test.class) Creates copies of the classes on the fly e.getClass().newInstance(); The most important functions of reflection mechanism, allowing the analysis of a class structure are located in three classes from java.lang.reflect •Field •Method •Constructor The use of reflection getType() Returns a Class object that identifies the declared type for the field represented by this Field object. getModifiers() Returns the Java language modifiers for the field represented by this Field object, as an integer. getParameterTypes() Returns an array of Class objects that represent the formal parameter types, in declaration order, of the method represented by this Method object. getReturnType() Returns a Class object that represents the formal return type of the method represented by this Method object. getModifiers() Returns the Java language modifiers for the constructor represented by this Constructor object, as an integer. getParameterTypes() Returns an array of Class objects that represent the formal parameter types, in declaration order, of the constructor represented by this Constructor object. Example: a generic array code Available in java.lang.reflect, class Array, allows to dynamically create or expand tables. Students[] stud = new Students[100]; //We want to expand table stud = (Students[])moreArray(stud); //moreArray() is our method Implementation of moreArray(): static Object goodArrayGrow(Object stud) { Class my = stud.getClass(); if (!my.isArray()) return null; Class componentType = my.getComponentType(); int length = Array.getLength(a); int biggerSize=length+10; Object biggerArray = Array.newInstance(componentType, biggerSize); System.arraycopy(a, 0, biggerArray, 0, length); return biggerArray; } Examining and modifying Enums Reflection provides three enum-specific APIs: Class.isEnum() Indicates whether this class represents an enum type Class.getEnumConstants() Retrieves the list of enum constants defined by the enum in the order they're declared java.lang.reflect.Field.isEnumConstant() Indicates whether this field represents an element of an enumerated type Fields which store enums are set and retrieved as any other reference type. field.set() public void set(Object obj,Object value); Sets the field represented by this Field object on the specified object argument to the specified new value. field.get(); Returns the value of the field represented by this Field, on the specified object. Reflection drawbacks Reflection is powerful, but should not be used blindly. If it is possible to perform an operation without using reflection, then avoid it. Performance Overhead Reflection involves types that are dynamically resolved, some JVM optimizations can not be performed. Consequently, reflective operations are much slower and should be avoided in loops. Security Restrictions Reflection requires a runtime permission which is not available under a security manager in a restricted security context (especially applets). Exposure of Internals Reflection allows to make operations that are illegal in non-reflective code (accessing private fields and methods). It can result in unexpected side-effects. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform.