我有一个可在其他通用类上运行的通用类:

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


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

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中的DistributionContextProviderBase

TResult中的DistributionService = TResult中的DistributionStrategyBase

我知道可以通过@SuppressWarnings(“ unchecked”)消除此警告,但是我很好奇是否还有其他方法可以正确地做到这一点。

最佳答案

类型参数的范围限于class或为其定义的方法。即使在两个类中都使用了TContext,它也不会超越类。现在已经解决了,让我们解决实际的问题。


  对我来说,似乎总是可以保证所有类型都可以
  从约束中使用的基类派生:


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

考虑以下情形:distributionContextProvider.getContext(input)返回DistributionContextBase,但是TContext中的DistributionService替换为DistributionContextBase的子类。以下强制转换将导致ClassCastException,并且编译器正在执行其工作并警告您相同的内容:

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

关于java - 当两个通用参数具有相同的上限时,未经检查的转换警告,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41939058/

10-09 18:30