One thing that is noticeable about the interface definitions presented here is that many of them pass an arbitrary data parameter which uses the Java root object type, Object. This may seem to be an anathema in the context of a strongly statically typed language such as Java, but there are valid reasons for making this design decision.
A key property of the Reaction framework is that it allows for the run-time dynamic configuration of program flow by attaching and triggering callbacks. As previously mentioned, this approach to dynamic programming is heavily influenced by the Twisted programming framework for Python. Python is inherently dynamically typed and the Twisted framework takes full advantage of this in its design. Fortunately Java also provides good support for dynamic type checking where required - it's just that its use is generally discouraged.
Given that it is not possible to carry out static type checking on dynamically configured callback structures, the two options available are to either perform run-time type checking while setting up the callbacks or to wait for a callback event and type check the data as it is passed to the callback. Of the two approaches, the latter is preferable since it is provided `free' by the run-time type checking implemented in the Java type-cast operator.
An example of using dynamic type checking on the opaque data objects is illustrated in Listing 1.7. Here the callback routine attempts to cast the opaque data object over to type Foo. If the passed parameter is in fact of type Foo the cast will succeed. However, if a passed parameter is not of a compatible type a class cast exception will be thrown which will be caught and logged by the framework for subsequent debugging.
By definition, opaque data objects hide the type of the data they contain. Therefore it is the responsibility of the programmer to ensure that the type of data generated in the callback is compatible with the type of data expected by a callback routine. Essentially this adds an extra non-syntactic element to defining and specifying API contracts.