当两个通用参数具有相同的上限时,取消选中转换警告

时间:2017-01-30 15:02:41

标签: java generics constraints

我有一个在其他泛型类上运行的泛型类:

public abstract class DistributionService<TInput extends DistributionInputBase,
                                TContextProvider extends DistributionContextProviderBase,
                                TContext extends DistributionContextBase,
                                TStrategy extends DistributionStrategyBase,
                                TResult extends DistributionResultBase> {
    private final TContextProvider _distributionContextProvider;

    public DistributionService(TContextProvider distributionContextProvider){
        _distributionContextProvider = distributionContextProvider;
    }

    //@SuppressWarnings("unchecked")
    public TResult GetResult(TInput input, TStrategy[] distributionStrategies){
        //unchecked cast warning
        TContext context = (TContext)_distributionContextProvider.getContext(input);
        TResult result = null;

        for (TStrategy strategy: distributionStrategies){
            //unchecked cast warning
            result = (TResult)strategy.Distribute(context);
            if (result != null)
                break;
        }

        return result;
    }
}

和TContextProvider和TStrategy类型在约束(DistributionContextBaseDistributionResultBase)中共享相同的基类型:

public abstract class DistributionContextProviderBase<TContext extends DistributionContextBase, TInput extends DistributionInputBase> {
    public abstract TContext getContext(TInput input);
    public abstract int getOpenIssueCount(Workforce workforce);
}

public abstract class DistributionStrategyBase<TContext extends DistributionContextBase, TResult extends DistributionResultBase> {
    protected WorkforceDistributionContext _context;

    protected String GetReason(TResult result){
        String reason = GetReasonSub(result);

        if (_context.HasRules()){
            reason += "\nRule(s) applied: " + _context.GetRules();
        }

        return reason;
    }

    public abstract TResult Distribute(TContext context);
    protected abstract TResult DistributeSub(TContext context);
    protected abstract String GetReasonSub(TResult result);
}

但是我在DistributionService类的注释中标记了“未经检查的强制转换”警告。对我来说,似乎始终保证所有类型都将从约束中使用的基类派生:

TContext中的DistributionService = TContext <{1}}

中的{p> DistributionContextProviderBase TResult中的DistributionService = TResult <{1}}

中的{p> DistributionStrategyBase

我知道用@SuppressWarnings(“未选中”)可以摆脱这个警告,但我很好奇是否还有其他方法可以正确地做到这一点。

1 个答案:

答案 0 :(得分:1)

type 参数的范围仅限于class或已定义的方法。 TContext并不超越类,即使它似乎在两个类中都使用过。现在这已经不在了,让我们解决实际问题。

  

对我而言似乎始终保证所有类型都是   派生自约束中使用的基类:

但是,等式两边的类型是否总是可以相互分配?请注意,语句distributionContextProvider.getContext(input);可以返回DistributionContextBase或任何子类。同时,TContext中的DistributionService可以替换为DistributionContextBase或其中任何子类。

考虑distributionContextProvider.getContext(input)返回DistributionContextBaseTContext中的DistributionService替换为DistributionContextBase的子类的情况。以下转换将导致ClassCastException并且编译器正在执行其工作并警告您大致相同:

TContext context = (TContext)_distributionContextProvider.getContext(input);