It is a common misconception that I hear when talking with clients that all information about generic types is erased from your Java class files. This is entirely untrue. All static generic information is maintained, and only generic information about individual instances is erased. So if I have a class Foo that implements List<String>, then I can determine that Foo implements the List interface parameterised by String at runtime. However, if I instantiate an instance of ArrayList<String> at runtime, I cannot take that instance and determine its concrete type parameter (I can determine that ArrayList requires type parameters). In this entry I’m going to show you a practical usage for some of the available generics metadata that simplifies the creation of strategy interfaces and implementations that differ by the type of object they process.
A pattern that I see occurring in many applications is the use of some kind of strategy interface with concrete implementations each of which handles a particular input type. For example, consider a simple scenario from the investment banking world. Any publicly traded company can issue Corporate Actions that bring about an actual change to their stock. A key example of this is a dividend payment which pays out a certain amount of cash, stock or property per shared to all shareholders. Within an investment bank, receiving notification of these events and calculating the resultant entitlements is very important in order to keep trading books up to date with the correct stock and cash values.
As a concrete example of this, consider BigBank which holds 1,200,000 IBM stock. IBM decides to issue a dividend paying $0.02 per share. As a result, BigBank needs to receive notification of the dividend action and, at the appropriate point in time, update their trading books to reflect the additional $24,000 of cash available.
The calculation of entitlement will differ greatly depending on which type of Corporate Action is being performed. For example, a merger will most likely result in the loss of stock in one company and the gain of stock in another.
If we think about how this might look in a Java application we could assume to see something like this (heavily simplified) example:
public class CorporateActionEventProcessor {
public void onCorporateActionEvent(CorporateActionEvent event) {
// do we have any stock for this security?
// if so calculate our entitlements
}
}
Notifications about events probably come in via a number of mechanisms from external parties and then get sent to this CorporateActionEventProcessor class. The CorporateActionEvent interface might be realised via a number of concrete classes:
public class DividendCorporateActionEvent implements CorporateActionEvent {
private PayoutType payoutType;
private BigDecimal ratioPerShare;
// ...
}
public class MergerCorporateActionEvent implements CorporateActionEvent {
private String currentIsin; // security we currently hold
private String newIsin; // security we get
private BigDecimal…