CSC302 2007S, Class 22: Introspection in Java Admin: * Are there questions on the exam? * Offline * Eldest son has a math competition on Wednesday. Dr. Stone teaches instead. * Anonymous inner classes * Since you're working on the exam, there is no reading or response necessary for Wednesday or Friday. * How many of you know generics in Java? * Probably on Friday * So, what did you learn from the videos? Overview: * Ideas from videos. * Introspection basics. * A problem: Factory Methods. * A problem: Dynamic Loading. * A problem: Serializing. * A problem: Profiling. /Ideas from Videos/ * Steele: Make small languages that can grow * Impossible to define everything someone might want * So you need good primitives and ways to combine them * Some growth comes in other ways - New language features so that your language can adapt * Extend the language when primitives and combinators work badly for that purpose * Steele: Designers need to accept user input - The language grows from such input * Stroustrup: Sometimes you design a language for the problems you have *now*, not the problems you expect to have ten years from now * And sometimes you end up with something much bigger than you expect * That does get applied to problems ten years in the future /Reflection and Introspection/ * Reflection is a way to get information about objects, classes, and methods at run time. * You're going back to what has already been done * Your program is reflecting on itself * Also called "introspection" - looking inside * In Java, supported by the following classes: * java.lang.Class * java.lang.reflect. * Array * Method * Constructor * Capabilities * You can get the name of a class or method or constructor at runtime * You can build methods, classes, etc. at runtime [NOPE] * You can change the values of an object's fields * You can invoke methods - In fact, you can query an object for a method with certain parameter types, and then invoke the method * You can build new objects (even if you don't know the name of the class) * *Why* would you want to do this? * In Eclipse, use the class browser * Why not rely on source code? * Because you don't always have the source code * Permits plug-ins * You can query the plug-ins for capabilities ("Hey, what interfaces do you implement?") * You can query the plug-ins for type signatures and build dialog boxes that obtain those types * At runtime, you can find which plugins are available and load them, even while running String[] possiblePlugins = FileSystem.ls("*.class"); for (int i = 0; i < possiblePlugins.length; i++) { Class c = Class.forName(possiblePlugins[i]); // Delete the .class if (c implements FOO) { addFoo(c.getConstructor(); .. /Some Scary Stuff about Reflection/ * What has happened to encapsulation? * Detour: Getting methods * All public methods (declared here, or superclass, or superduperclass or, ...) * All methods declared here (public, private, protected, package) * Answer: Encapsulation? We don't need or want encapsulation! * What has happened to static type checking? * Answer: We want to make Java more like Lisp * And at least there's a clear way to identify the runtime type errors - Exceptions /Why else use reflection?/ * Many instances in which you need to know more than encapsulation permits * Example: Storing objects to disk * I have to store Foo to disk, and Foo is encapsulated * When you have the source code: Write toWritableString and fromWritableString * A problem: Lots and lots of effort, particularly if you have many classes * Solution: Automatically generate the procedures * A problem: Mutually linked structures * Solution: Create "pointers" for the disc, too * The traditional Java solution: "implements Serializable" * The stuff related to serialization is implemented using reflection * We could also implement it using reflection * Get the list of fields (public and private) * Primitive things can be written directly * Other objects we generate identifier and recurse * Factory methods (sometimes) * We write programs, and somewhere in the program we need to generate a lot of objects whose type we don't know at compile time * List of the squares of the whole numbers from 1 to n * Might be Integer * Might be Double * Might be BigInteger * Things that build objects are called factories * For this example, we might even be able to pass in the one-parameter constructor