Java8中用log方法规避forEach的try-catch时遇类型匹配错误求助
解决Map.forEach中使用自定义log()方法的类型不匹配问题
我来帮你搞定这个红色波浪线的问题!你遇到的错误本质是泛型类型不匹配——你的log()方法返回的是Consumer<T>(只能接收单个参数的函数式接口),但Map.forEach()需要的是BiConsumer<K, V>(能接收两个参数:Map的key和value),编译器没法正确推断泛型参数,才会把job和type的类型搞错,进而导致runJob()的参数不匹配提示。
下面给你两种可行的解决方案:
方案1:新增支持BiConsumer的log()重载方法
这是最贴合你原有调用习惯的方案,我们给log()新增一个专门处理双参数场景的重载版本:
// 新增针对双参数场景的log重载 public <K, V> BiConsumer<K, V> log(LogBiConsumer<K, V, Throwable> logBiConsumer) { return (k, v) -> { try { logBiConsumer.accept(k, v); } catch (Throwable e) { log("e = " + e); } }; } // 对应的双参数函数式接口 @FunctionalInterface public interface LogBiConsumer<K, V, E extends Throwable> { void accept(K k, V v) throws E; }
修改后的execute()方法可以保持你原来的调用写法,编译器现在能正确推断job和type的类型:
execute() { Map<Job, JobType> map = getJobMap(); // 现在不会再出现类型错误 map.forEach(log((job, type) -> new Task().runJob(job, type))); }
方案2:遍历Map的entrySet适配原有log()方法
如果你不想新增方法和接口,可以通过遍历Map.entrySet()来适配你现有的log()方法(它只接收单参数的Consumer):
execute() { Map<Job, JobType> map = getJobMap(); // 把每个Map.Entry作为单参数传给log() map.entrySet().forEach(log(entry -> new Task().runJob(entry.getKey(), entry.getValue()) )); }
这样做的原理是,entrySet()返回的是Set<Map.Entry<Job, JobType>>,它的forEach()方法接收Consumer<Map.Entry<Job, JobType>>,刚好和你原有log()方法返回的类型匹配,编译器能正确识别entry.getKey()是Job类型,entry.getValue()是JobType类型,自然就不会报错了。
内容的提问来源于stack exchange,提问作者user2761895
相关产品推荐
相关产品推荐

