我在与客户交流时,常听到一种普遍的误解,认为所有泛型类型信息都已从 Java 类文件中擦除。这完全是错误的。所有静态泛型信息都会被保留,只有关于个体实例的泛型信息会被擦除。所以如果我有一个类 Foo 实现了 List<String>,那么我可以在运行时确定 Foo 实现了由 String 参数化的 List 接口。然而,如果我在运行时实例化一个 ArrayList<String> 的实例,我无法通过该实例确定其具体的类型参数(我可以确定 ArrayList 需要类型参数)。在这篇文章中,我将向您展示一些可用泛型元数据的实际用法,这些元数据简化了根据它们处理的对象类型而不同的策略接口和实现的创建。
我在许多应用程序中看到的一种模式是使用某种策略接口,每个具体的实现都处理特定的输入类型。例如,考虑一个投资银行领域的简单场景。任何上市公司都可以发布公司行动,从而对其股票产生实际变化。一个关键例子是股息支付,它按每股向所有股东支付一定金额的现金、股票或财产。在投资银行内部,接收这些事件通知并计算由此产生的权益非常重要,以保持交易账簿的股票和现金价值准确无误。
举个具体例子,考虑持有 1,200,000 股 IBM 股票的 BigBank。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…