Introflection Dave Landers BEA Systems, Inc. dave.landers@bea.com
Agenda What is Introflection? Primary Classes and Objects Loading Classes Creating Objects Invoking Methods Java Beans Proxy
What is Introflection? Reflection plus Introspection Public Domain form of Skintroflection ejskin Product Launch at Colorado Software Summit 2000
Reflection Dynamic discovery of information about a Class Fields Methods Constructors Interfaces and Superclasses Use of this information Construct classes Invoke Methods Set Fields Dynamic Proxy
Introspection Gather information about a Java Bean Properties Events Methods Uses Bean s BeanInfo class, if available Otherwise uses Reflection and applies Design Patterns
Factory Example Uses of Reflection Construct objects not known at compile time Specified thru properties, command line, etc. Method Interception Testing, debugging, logging What is that system doing with this class? Add behavior when you can t subclass, etc. Discover capabilities of objects and classes Code Inspection Testing and analysis tools Code generation tools
When NOT to Use Reflection When an Interface will do the job If you can capture the API in an Interface, then do it When a design pattern or API exists Look at existing patterns to see if the problem has been solved
Reflection Classes java.lang.class java.lang.reflect.method java.lang.reflect.constructor java.lang.reflect.field java.lang.reflect.modifier java.lang.reflect.array java.lang.reflect.proxy java.lang.reflect.invocationhandler
java.lang.class Represents a class Starting point for all reflection operations Gives you information about the class Name, Package Interfaces, Superclasses Methods, Fields, Constructors Protection and Modifiers Abstract, Interface, or Concrete Can instantiate objects
Class Instances How do you get a Class instance? Dynamically load a Class By name Reference a Class by Name Using the class keyword Get the Class for an Object getclass()
Dynamic Class Loading Class.forName(String classname) Class c = Class.forName("java.lang.String"); Use the full class name (with package) Loads and initializes the class No compiler check on the class name Careful of errors in the name string No need to know the class name until runtime
Exceptions - Class.forName() ClassNotFoundException If the class can not be loaded LinkageError Incompatible change in dependant class ExceptionInInitializerError Static initializer threw exception
The class keyword Class c = String.class; More convenient than Class.forName() If you know the class name at compile time Compiler verifies that class exists Does not throw checked exceptions Unless class becomes unavailable at runtime Generates synthetic methods and fields Uses Class.forName() internally Except for primitives (int.class Integer.TYPE)
Get the Class for an Object anobject.getclass() Returns the runtime type of the object instance Not the declared type Example Object foo = new String( ); foo has declared type Object The instance of foo is a String foo.getclass() will return String.class
Object.getClass() Better than MyClass.class if you have an object of the right type No need to bother the ClassLoader The class is already loaded and the Object knows its type Use.getClass() rather than String.class No generated synthetic methods Remember, they use Class.forName() internally Careful of declared vs. runtime types
Class and Arrays Class[] is NOT the same as the Class object for an array Use class keyword just as with other types int[][].class not int.class[][] Building array classes with Class.forName() is weird Same weird name is output by getname [Ljava.lang.Object; not java.lang.object[] Try Array.newInstance(Foo.class,0).getClass()
Object Creation aclass.newinstance() Returns a new object instance for the Class Uses default constructor Class c = Class.forName( FooImpl ); Foo thefoo = (Foo) c.newinstance(); Same as Foo thefoo = new FooImpl();
Class.newInstance() Exceptions These would be checked by the compiler if we were not doing reflection... InstantiationException Can not instantiate - abstract, primitive, etc. No default constructor IllegalAccessException Class was not public, etc. ExeptionInInitializerError Static initialization failed
And Class.newInstance() Exceptions Throws whatever the constructor throws Even checked Exceptions! But wait? Class.newInstance() only declares InstantiationException, IllegalAccessException See example ExceptionTest
Exceptions - Class.newInstance() Java Language Spec, First Edition, Section 20.3.6: If evaluation of [the equivalent] class instance creation expression would complete abruptly, then the call to the newinstance method will complete abruptly for the same reason. No mention in JLS-2
Try This try { myclass.newinstance(); } catch (MyException e) { } Won t compile Compiler will not let you catch undeclared exception Should usually catch a generic Throwable Use instanceof to check for known types
Constructors with Arguments java.lang.reflect.constructor Mostly like Method We ll look at Method later Has newinstance() method vs. Method s invoke aclass.getconstructor(class[] params) aclass.getconstructors() aclass.getdeclaredconstructor(...) aclass.getdeclaredconstructors()
Exceptions Constructor.newInstance() InstantiationException IllegalAccessException ExceptionInInitializerError IllegalArgumetException Arguments don t match InvocationTargetException If the Constructor throws anything gettargetexception() To retrieve the original Throwable
Code Break ThingFactory Returns an implementation of a Thing Based on System Property This is a common pattern Other common Factory sensors Operating System GUI or Command Line or Server mode Thread state or Application Status Configuration objects
java.lang.reflect.method Access information about a method Protection and Modifiers public, private, static, synchronized, etc. Declaring class Parameters Exceptions Return type Can invoke methods Method.invoke()
Get a Method from Class aclass.getmethod( String name, Class[] argtypes ) Get a particular public method Looks in this class and all super-classes Parameters must be exactly as declared public void foo(number num); Will not be found with getmethod("foo", new Class[] { Integer.class } ); Even though Integer extends Number
Other Method methods aclass.getmethods() Gets array of all public methods in this class and all superclasses aclass.getdeclaredmethod(...) aclass.getdeclaredmethods() Any method (not just public) Only those that are declared in the class No inherited methods Use aclass.getsuperclass()
Method Invocation amethod.invoke( Object obj, Object[] args ) Invoke a method on obj Like obj.method(args[0], args[1], ); obj must be instance of declaring Class of method Use null for static methods args are the method s parameters Must match method s parameter types Primitives should be wrapped Example: use Integer if method takes int Cast return to the method s return type Primitive return types will be wrapped
Method Invocation Exceptions getmethod() NoSuchMethodException There is no method with that signature invoke() IllegalAccessException Method was private, etc. IllegalArgumentException Arguments don t match parameters InvocationTargetException The method threw an exception Use gettargetexception() to get the original exception
Code Break AutoConfiguration Abstract base class Automatically set up a Configuration object from System Properties Automatically maps set methods to corresponding properties in subclasses MyConfiguration extends AutoConfiguration Concept can be applied to Servlets, Applets, GUIs, etc.
Code Break? ActionDispatcher Implements ActionListener Gets ActionCommand from event Uses that as a method name Executes method in response to the action DispatchExample.java Creates some buttons Sets ActionCommand to method name
Introspection Java Beans Introspector BeanInfo
Java Beans Bean properties and events match Design Pattern getfoo() & setfoo() Property named foo Introspector figures this out
java.beans.introspector Retrieve BeanInfo for a Java Bean Or any class that follows Java Beans Design Pattern Introspector.getBeanInfo() BeanInfo Information on Properties Methods Events More
Introspector Uses BeanInfo class if available Bean named Foo might have FooBeanInfo in some package in bean info search path Introspector uses this if available Skips reflection BeanInfo can be used for Tricks Remapping properties, methods to different names Can set getfoo() and setbar() for property baz
BeanInfo abeaninfo.getpropertydescriptors() PropertyDescriptor getname() getpropertytype() getreadmethod getwritemethod() getbeandescriptor() getmethoddescriptors() geteventsetdescriptors()
Code Break AutoConfiguration implementation using Introspector BeanInfo example
Dynamic Proxy Proxies Delegation Method Interception Wrapping classes with extra implementation Aspect Oriented Programming Dynamic Implementations
Proxy Proxy & InvocationHandler New in JDK 1.3 Generates classes That implement your interface(s) At runtime Actually feeds bytecodes to a ClassLoader Cool! All methods on the interfaces call InvocationHandler.invoke() You write this
Proxy Proxy.newProxyInstance( ClassLoader classloader, Class[] interfaces, InvocationHandler handler ) There are other ways to create a Proxy, but this is the simplest Returns an object that implements all interfaces Can be cast to any of those interfaces
InvocationHandler public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable proxy The object on which the method was called method The method that was called args The arguments that were passed Returns whatever the method should return Throws whatever exception the method throws
Code Break LoggingProxy Wrap it around any object that implements an interface and all method calls are logged Example what are they doing with my database? Connection c = (Connection) LoggingProxy.newProxyInstance( myconn ); they.setconnection( c );
Code Break Magic Bean Magic interface implementer Knows about get/set methods Only need to provide partial implementation of some methods Great idea for configuration objects Repetitive get/set implementations are boring Magic implementation could be extended with Persistence and Initialization File, Database, JMX, etc.
Conclusion Introflection is a powerful tool But Skintroflection is better Innovation Without Effort principals Dynamic Class and Object creation Method Invocation Proxies Use in conjunction with Interfaces Design Patterns OO practices Watch out for those Exceptions
References The Java Language Specification http://java.sun.com/docs/books/jls/index.html Reflection and Proxy Overview http://java.sun.com/j2se/1.3/docs/guide/reflection/index.html Installed JDK: docs/guide/reflection/index.html Reflection Tutorial http://java.sun.com/docs/books/tutorial/reflect/index.html
References JavaBeans Spec http://java.sun.com/javabeans/docs/specs.html JavaBeans Docs http://java.sun.com/j2se/1.3/docs/guide/beans/index.html Installed JDK: docs/guide/beans/index.html JavaBeans Tutorial http://java.sun.com/docs/books/tutorial/javabeans/index.html
References ejskin Colorado Software Summit 2000 CD-ROM
Thank You Please fill out the Evaluations Examples On the CD Can t wait? http://www.avitek.com/landers/introflection.zip Reflection Beyond the Class class (CSS, 1999) http://www.avitek.com/landers/reflection.zip