具有泛型重载(非重写)的Java擦除

具有泛型重载(非重写)的Java擦除,java,generics,overloading,type-erasure,Java,Generics,Overloading,Type Erasure,我在我的领域有财务请求和佣金交易。 如果我有一个FinanceRequests列表,每个FinanceRequest可能包含多个需要收回的佣金交易。不要担心这到底是怎么做到的 下面的类(最底层)让我感觉非常模糊和温暖,因为它简洁并且很好地重用了现有代码。一个问题类型是擦除 public void clawBack(Collection<FinanceRequest> financeRequestList) public void clawBack(Collection<Co

我在我的领域有财务请求和佣金交易。 如果我有一个FinanceRequests列表,每个FinanceRequest可能包含多个需要收回的佣金交易。不要担心这到底是怎么做到的

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

public void clawBack(Collection<FinanceRequest> financeRequestList)  
public void clawBack(Collection<CommissionTrns> commissionTrnsList)
公共作废收回(收款人请求列表)
公共作废收回(托收佣金TRNSLIST)
他们在擦除后都有相同的签名,即:

Collection<FinanceRequest> --> Collection<Object>  
Collection<CommissionTrns> --> Collection<Object>  
集合-->集合
集合-->集合
所以eclipse抱怨:
方法回调(集合)与CommissionFacade类型中的另一个方法具有相同的擦除回调(集合)

有没有建议重新构造它,使它仍然是一个优雅的解决方案,可以实现良好的代码重用


public class CommissionFacade
{
/********财务要求****************/
公共无效追回(FinanceRequest FinanceRequest)
{
集合commTrnsList=financeRequest.getCommissionTrnsList();
这是一种回扣(commTrnsList);
}
公共无效回扣(收款人请求列表)
{
对于(FinanceRequest finReq:financeRequestList)
{
这是指追回(finReq);
}           
}
/********佣金交易****************/
公共无效回扣(佣金TRNS佣金TRNS)
{
//对单次佣金进行扣回
}
公共作废收回(托收佣金TRNSLIST)
{
对于(CommissionTrns commTrn:commissionTrnsList)
{
这是回拨(commTrn);
}
}
}

我认为最好的选择是简单地用不同的方法命名

public void clawBackFinReqs(Collection<FinanceRequest> financeRequestList) {

}

public void clawBackComTrans(Collection<CommissionTrns> commissionTrnsList) {

}
public-void-paulf-inreq(收款人请求列表){
}
公共无效回扣交易(托收佣金交易清单){
}
事实上,这也不算太糟,因为在它们上面有相同的名字并不会带来任何额外的好处


请记住,JVM将而不是决定在运行时调用哪个方法。与虚拟方法相反,重写重载方法的解析在编译时完成。上的Java教程甚至指出“重载的方法应该少用……”。

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

使用对象中的代码,这些对象将是:

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
    }

}
可收回的公共接口{
无效回拨()
}
公共阶级委员会
{
公共无效回扣(集合对象)
{
对于(T对象:对象)
{
object.clawBack();
}           
}
}
公共类CommissionTrns实现可收回{
公共无效追回(){
//收取佣金要回扣吗
}
}
公共类FinanceRequest实现可收回{
公共无效追回(){
//是否为FinanceRequest进行回拨
}
}
我更喜欢这种方法,因为我相信你的领域应该包含你的逻辑;但我不完全了解你的确切愿望,所以我会让你决定


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

我也喜欢这种方法,并同意逻辑应该在域中。我的示例感觉很像一个助手或UTIL类,我更愿意避免它。谢谢Joeri,这是一个优雅的解决方案。您给出这个解决方案时,好像它是某种妥协,但我认为必须重命名这些方法。实际上,带有单个参数的重载方法也必须重命名。这些重载方法的代码现在还不清楚,这个答案并不完全令人满意,尤其是Java教程中提到的重载会降低代码的可读性是非常主观的。问题在于,接口的实现通常是可共享的。以一个简单的接口为例:MyType提供(类类型),其中类型充当鉴别器。当没有可能通过类型来区分“泛型”时,我们被迫重命名,但独立接口可能使用不同的名称来达到相同的目的,这就不必要地负担实现。例如,使用Boosi::MPL::C++中的身份基于类型进行区分,简化函数名的选择并允许通用实现。
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
    }

}