4.7. Types, Reflection, and Dynamic LoadingThe java.lang.Class class represents data types in Java and, along with the classes in the java.lang.reflect package, gives Java programs the capability of introspection (or self-reflection); a Java class can look at itself, or any other class, and determine its superclass, what methods it defines, and so on. There are several ways you can obtain a Class object in Java: // Obtain the Class of an arbitrary object o Class c = o.getClass(); // Obtain a Class object for primitive types with various predefined constants c = Void.TYPE; // The special "no-return-value" type c = Byte.TYPE; // Class object that represents a byte c = Integer.TYPE; // Class object that represents an int c = Double.TYPE; // etc. See also Short, Character, Long, Float. // Express a class literal as a type name followed by ".class" c = int.class; // Same as Integer.TYPE c = String.class; // Same as "dummystring".getClass() c = byte[].class; // Type of byte arrays c = Class[][].class; // Type of array of arrays of Class objects
Once you have a Class object, you can perform some interesting reflective operations with it: import java.lang.reflect.*; Object o; // Some unknown object to investigate Class c = o.getClass(); // Get its type // If it is an array, figure out its base type while (c.isArray()) c = c.getComponentType(); // If c is not a primitive type, print its class hierarchy if (!c.isPrimitive()) { for(Class s = c; s != null; s = s.getSuperclass()) System.out.println(s.getName() + " extends"); } // Try to create a new instance of c; this requires a no-arg constructor Object newobj = null; try { newobj = c.newInstance(); } catch (Exception e) { // Handle InstantiationException, IllegalAccessException } // See if the class has a method named setText that takes a single String // If so, call it with a string argument try { Method m = c.getMethod("setText", new Class[] { String.class }); m.invoke(newobj, new Object[] { "My Label" }); } catch(Exception e) { /* Handle exceptions here */ }
Class also provides a simple mechanism for dynamic class loading in Java. For more complete control over dynamic class loading, however, you should use a java.lang.ClassLoader object, typically a java.net.URLClassLoader. This technique is useful, for example, when you want to load a class that is named in a configuration file instead of being hardcoded into your program: // Dynamically load a class specified by name in a config file String classname = // Look up the name of the class config.getProperties("filterclass", // The property name "com.davidflangan.filters.Default"); // A default try { Class c = Class.forName(classname); // Dynamically load the class Object o = c.newInstance(); // Dynamically instantiate it } catch (Exception e) { /* Handle exceptions */ } // If the class to be loaded is not in the classpath, create a custom // class loader to load it. // Use the config file again to specify the custom path import java.net.URLClassLoader; String classdir = config.getProperties("classpath"); try { ClassLoader loader = new URLClassLoader(new URL[] { new URL(classdir) }); Class c = loader.loadClass(classname); } catch (Exception e) { /* Handle exceptions */ }
Copyright © 2001 O'Reilly & Associates. All rights reserved. |
|