我在与客户交谈时经常听到一个常见的误解,即所有关于泛型类型的信息都从 Java 类文件中被擦除。这完全是错误的。所有静态泛型信息都会被保留,只有关于单个实例的泛型信息才会被擦除。所以如果我有一个类 Foo 实现了 List<String>,那么我可以在运行时确定 Foo 实现了由 String 参数化的 List 接口。然而,如果我在运行时实例化一个 ArrayList<String> 的实例,我不能获取该实例并确定其具体类型参数(我只能确定 ArrayList 需要类型参数)。在这篇文章中,我将向你展示一些可用的泛型元数据的实际用法,它简化了根据处理对象类型而不同的策略接口和实现的创建。
我在许多应用程序中看到的一种模式是使用某种策略接口,其具体实现分别处理特定的输入类型。例如,考虑投资银行业务中的一个简单场景。任何上市公司都可以发布公司行为,从而导致其股票发生实际变化。一个主要例子是股息支付,它按每股向所有股东支付一定数量的现金、股票或财产。在投资银行内部,接收这些事件的通知并计算由此产生的权益非常重要,以便使交易账簿与正确的股票和现金价值保持同步。
作为一个具体示例,考虑 BigBank 持有 1,200,000 股 IBM 股票。IBM 决定派发每股 0.02 美元的股息。因此,BigBank 需要接收股息行动的通知,并在适当的时间更新其交易账簿,以反映额外的 24,000 美元可用现金。
权益的计算将根据执行的公司行动类型而有很大差异。例如,合并很可能导致一家公司的股票损失和另一家公司的股票增加。
如果我们考虑这在 Java 应用程序中可能是什么样子,我们可以假设会看到类似(大大简化)的示例
public class CorporateActionEventProcessor {
public void onCorporateActionEvent(CorporateActionEvent event) {
// do we have any stock for this security?
// if so calculate our entitlements
}
}
关于事件的通知可能通过多种机制从外部方传入,然后发送到这个 CorporateActionEventProcessor 类。CorporateActionEvent 接口可能通过许多具体类实现
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…