Java的擦除与通用超载(未覆盖)(Java erasure with generic overlo

2019-06-26 09:00发布

我有我的域名FinanceRequests和CommisionTransactions。 如果我有FinanceRequests的列表中的每个FinanceRequest可能包含需要被收复多个CommisionTransactions。 不要担心,究竟如何做到这一点。

下面的类(最底层)让我觉得因为它的succint所有模糊和温暖,并很好地重用现有的代码。 一个问题类型擦除。

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

他们都有擦除,即在相同的签名:

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

所以日食complainst说:
方法回拨(集合)具有相同的擦除回拨(集合),如类型CommissionFacade另一种方法

任何建议,以使得它仍然是一个很好的解决方案,使良好的代码重用重组呢?


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);
        }
    }

}

Answer 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”的回拨方法,并在处理程序调用取决于类型适当的方法。



Answer 2:

我觉得你最好的选择是简单地不同的命名方法。

public void clawBackFinReqs(Collection<FinanceRequest> financeRequestList) {

}

public void clawBackComTrans(Collection<CommissionTrns> commissionTrnsList) {

}

事实上,这不是太糟糕了,因为你没有得到任何额外的东西出来有关于他们的同名。

请记住,该JVM 不会决定在运行时调用哪个方法。 相对于虚拟方法/方法的重载方法重写分辨率是在编译时进行。 Java教程的方法重载甚至指出,“重载方法应尽量少用......”。



文章来源: Java erasure with generic overloading (not overriding)