使用通用重载(不覆盖)的 Java 擦除

2022-09-02 11:03:07

我的域中有 FinanceRequests 和 CommisionTransactions。如果我有一个财务请求列表,每个财务请求可能包含多个需要抓回的Commmision交易。不要担心这到底是怎么做到的。

下面的类(非常底部)让我感到所有模糊和温暖,因为它简洁且很好地重用了现有代码。一个问题 类型擦除。

public void clawBack(Collection<FinanceRequest> financeRequestList)  
public void clawBack(Collection<CommissionTrns> commissionTrnsList)

它们都在擦除后具有相同的签名,即:

Collection<FinanceRequest> --> Collection<Object>  
Collection<CommissionTrns> --> Collection<Object>  

因此,Eclipse抱怨说:
方法clawBack(Collection)与CommissionFacade类型的另一种方法具有相同的擦除lawBack(Collection)。

任何建议来重构它,以便它仍然是一个优雅的解决方案,使良好的代码重用?


public class CommissionFacade
{
    /********FINANCE REQUESTS****************/
    public void clawBack(FinanceRequest financeRequest)
    {
        Collection<CommissionTrns> commTrnsList = financeRequest.getCommissionTrnsList();           
        this.clawBack(commTrnsList);
    }

    public void clawBack(Collection<FinanceRequest> financeRequestList)
    {
        for(FinanceRequest finReq : financeRequestList) 
        {
            this.clawBack(finReq);
        }           
    }

    /********COMMISSION TRANSACTIOS****************/
    public void clawBack(CommissionTrns commissionTrns)
    {
        //Do clawback for single CommissionTrns         
    }

    public void clawBack(Collection<CommissionTrns> commissionTrnsList)
    {
        for(CommissionTrns commTrn : commissionTrnsList) 
        {
            this.clawBack(commTrn);
        }
    }

}

答案 1

重命名方法,或使用多态性:使用接口,然后将抓回代码放在对象本身中,或使用双重调度(取决于您的设计范例和品味)。

使用对象中的代码,可以是:

public interface Clawbackable{
    void clawBack()
}


public class CommissionFacade
{

    public <T extends Clawbackable> void clawBack(Collection<T> objects)
    {
        for(T object: objects) 
        {
            object.clawBack();
        }           
    }
}

public class CommissionTrns implements Clawbackable {

    public void clawback(){
       // do clawback for commissions
    }
}

public class FinanceRequest implements Clawbackable {

    public void clawBack(){
      // do clwaback for FinanceRequest
    }

}

我更喜欢这种方法,因为我相信你的领域应该包含你的逻辑;但我不完全知道你的确切愿望,所以我把它留给你。

使用双重调度,您可以将“ClawbackHandler”传递给clawback方法,并在处理程序上根据类型调用适当的方法。


答案 2

我认为你最好的选择是简单地以不同的方式命名方法。

public void clawBackFinReqs(Collection<FinanceRequest> financeRequestList) {

}

public void clawBackComTrans(Collection<CommissionTrns> commissionTrnsList) {

}

事实上,这并不是太糟糕,因为你不会从它们上面有相同的名字中得到任何额外的东西。

请记住,JVM 不会决定在运行时调用哪个方法。与虚方法相反/方法重写重载方法的分辨率是在编译时完成的。关于方法重载的Java教程甚至指出“应谨慎使用重载方法......”