Table of Contents
Contents
preface xiii
acknowledgments xv
about this book xvii
about the title xx
about the cover illustration xxi
- 1 A few basics 1
- Reflection's value proposition 3
- Enter George the programmer 4
- Choosing reflection 5 - Programming a reflective solution 6
- Examining running programs 8
- Finding a method at runtime 10
- Representing types with class objects 12
- Representing primitive types 13 - Representing interfaces 13 - Representing array types 14
- Understanding method objects 14
- Using dynamic invocation 15 - Using primitives with dynamic invocation 16 - Avoiding invocation pitfalls 17
- Diagramming for reflection 19
- Navigating the inheritance hierarchy 20
- Introspecting the inheritance hierarchy 22 - Exposing some surprises 23 - Another reflective circularity 24
- Summary 26
 
- 2 Accessing fields reflectively 27
- Serializing objects 28
- Serializing to XML 29 - Choosing reflection 30 - Designing serialization with reflection 30
- Finding fields at runtime 31
- Understanding field objects 33
- Getting and setting field values 34
- Examining modifiers 35
- Introducing Member 36 - Interface introspection pitfall 37 - Introspecting for instance variables 37
- Accessing nonpublic members 38
- Working with arrays 40
- Serialization: putting it all together 41
- Serializing each component 43 - Serializing instance variables 43
- Using reflective serialization 45
- Summary 48
 
- 3 Dynamic loading and reflective construction 49
- George's deployment problem 50
- Designing with patterns 51 - Programming a reflective solution 52 - Enhancing the factory method with reflection 54 - Combining - benefits of delegation and reflection 54
- Loading classes dynamically 55
- Basics of forName 55 - Getting array classes 56 - Primitives and forName 56
- Constructing objects reflectively 57
- Reflective construction basics 57 - Using constructor objects 57 - Constructing arrays reflectively 59
- Designing for dynamic loading 60
- Disadvantages of reflective construction with arguments 61 - Initializing through an interface 62
- Implementing deserialization 63
- Initiating deserialization 64 - Constructing the instances 65 - Restoring the object structure 66
- George's serialization: limitations 69
- No interaction with readObject or writeObject 69 - No handling of
final instance variables 70 - Only no-argument constructors 70 - No handling of illegal XML characters 70 - Performance 71
- Summary 71
 
- 4 Using Java's dynamic proxy 73
- Working with proxies 74
- George's tracing problem 76
- Exploring Proxy 77
- Understanding invocation handlers 79 - Handling the methods of Object 80
- Implementing a tracing proxy 81
- A note on factories 84
- Chaining proxies 86
- Structuring invocation handlers for chaining 86 - Implementing
a synchronized proxy 88 - Chaining the two proxies 89
- Stubbing interfaces for unit testing 90
- Examining stubs 90 - Design for stubbing with Proxy 91 - Implementation of stubbing with Proxy 93
- Generating SOAP remote proxies 99
- Pitfalls of using Proxy 103
- Summary 105
 
- 5 Call stack introspection 107
- George's logging problem 108
- Performing call stack introspection 111
- Logging with call stack introspection 112
- Pitfalls 114
- Class invariant checking 115
- Summary 120
 
- 6 Using the class loader 121
- George's test problem 122
- Essentials of ClassLoader 123
- Understanding the delegation model 123 - Programming a simple
class loader 127 - Reinitializing static fields: a solution 128
- Multiple namespaces 130
- Dynamic class replacement 132
- Designing for replacement 132 - Implementing replacement 134 - Simplifying assumptions 137
- Additional considerations 138
- Security 139 - Don't reinvent the wheel 139 - Modifying bytecode in a class loader 140 - When not to invent a specialized class loader 140 - Additional examples 141 - Endorsed Standards - Override 142
- Summary 142
 
- 7 Reflective code generation 143
- Reflective code generation 143
- Generating HelloWorld.java 145
- Class-to-class transformation framework 147
- C2C 148 - Args 152 - C2CConstructor 154 - C2CTransformation 157
- Example: extent management 159
- C2IdentitySubclassOfC and its subclasses 168
- UQueue 170
- Using the framework 173
- Relation to Aspect-Oriented Programming 175
- Summary 176
 
- 8 Design patterns 179
- Singleton 181
- Decorator class-to-class transformations 187
- Proxy (again) 197
- Another composition feature 201
- Problematic issues in writing class-to-class transformations 201
- Summary 204
 
- 9 Evaluating performance 207
- Evaluating performance 207
- Categorizing performance impact 209
- Using microbenchmarks 210
- Benchmarking two ways to use Proxy 214
- Understanding Amdahl's Law 218
- Applying Amdahl's Law 221
- Summary 223
- 10 Reflecting on the future 225
- Looking forward: Java 1.5 226
- JSR 14-Generics 227 - JSR 175-Annotation Facility 229 - JSR 201-Language extensions 234 - Impact of Java 1.5 on reflective code 235
- Looking forward: competition for Java reflection 236
- C# 236 - Python 236 - Smalltalk 236 - CLOS 237 - Ruby 237 - Perl 237
- Looking forward: Aspect-Oriented Programming 237
- Looking forward: your career 238
 
appendix A Reflection and metaobject protocols 241
appendix B Handling compilation errors in the "Hello world!" program 253
appendix C UML 256
glossary 258
references 260
index 267