具有泛型重载的Java擦除(不覆盖)

n4r*_*zul 15 java generics overloading type-erasure

我的域名中有FinanceRequests和CommisionTransactions.如果我有一个FinanceRequests列表,每个FinanceRequest可能包含多个需要回收的CommisionTransactions.不要担心这是怎么做到的.

下面的课程(非常底层)让我感觉自己的模糊和温暖,因为它很好地重用现有的代码.一个问题类型擦除.

public void clawBack(Collection<FinanceRequest> financeRequestList)  
public void clawBack(Collection<CommissionTrns> commissionTrnsList)
Run Code Online (Sandbox Code Playgroud)

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

Collection<FinanceRequest> --> Collection<Object>  
Collection<CommissionTrns> --> Collection<Object>  
Run Code Online (Sandbox Code Playgroud)

所以eclipse抱怨说:
方法clawBack(Collection)具有相同的擦除clawBack(Collection)作为类型为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);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

Joe*_*ckx 14

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

使用对象中的代码:

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
    }

}
Run Code Online (Sandbox Code Playgroud)

我更喜欢这种方法,因为我相信你的域应该包含你的逻辑; 但我并不完全清楚你的确切意愿,所以我会把它留给你.

使用双分派,您可以将"ClawbackHandler"传递给clawback方法,并在处理程序上根据类型调用适当的方法.


aio*_*obe 6

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

public void clawBackFinReqs(Collection<FinanceRequest> financeRequestList) {

}

public void clawBackComTrans(Collection<CommissionTrns> commissionTrnsList) {

}
Run Code Online (Sandbox Code Playgroud)

实际上,这还不错,因为在它们上使用相同的名称不会给您带来任何额外的好处。

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

  • 您提供的解决方案好像是某种妥协,但我认为必须将这些方法重命名。实际上,具有单个参数的重载方法也必须重命名。现在,这些重载方法的代码还不清楚。 (2认同)