Eclipse 将(工作中的)代码标记为编译错误并且不会 运行

Eclipse flags (working) code as compilation error and will not run

我有一些使用 Javaslang 的相当复杂的代码。如果我将它编译成一个 jar,它 运行 没问题。但是,当我尝试在 Eclipse 中进入它进行调试时,Eclipse 将其标记为编译错误并在到达该行时终止。特别奇怪的是,这在一周前就成功了,而代码在此期间没有改变。

我尝试过的事情:

Maven 可以毫无错误地构建它 [在 Eclipse 中和从命令行]。我可以 运行 这个依赖的项目并让它从 JAR 访问这个代码,所以我知道它有效。我无法让 Eclipse 在 'run' 或 'debug' 模式下访问项目中的代码。

    Seq<Tuple2<StateProbabilityVector, ScenData>> resultStateProbs =
        futures.
            flatMap(Future::get).
            toList();

    // Update the target counts.
    // THIS ENTIRE STATEMENT IS THE ERROR
    Seq<Tuple2<ScenState, Probability>> result =
        resultStateProbs.flatMap(tuple -> tuple.apply((spv, baTargetCount) ->
    {
        return spv.getStateProbList().
        peek(sp -> logger.debug("Checking if {} > {}: {}",
                               sp.getProbability(),
                               intermediateMinProb,
                               sp.getProbability().greaterThan(intermediateMinProb))).
        filter(sp -> sp.getProbability().greaterThan(intermediateMinProb)).
        map(sp -> updateScenarioData(sp, baTargetCount, dupStateInfo));
    }));

// signature for updateScenarioData
protected abstract Tuple2<ScenState, Probability> updateScenarioData(StateProbability stateProb,
                                                                         ScenData scenData,
                                                                     DSI dupStateInfo);
// truncated def of StateProbabilityVector
@Getter @ToString @Builder
public class StateProbabilityVector {
 @NonNull
    private final Seq<StateProbability> stateProbList;
}

所以类型都是正确的,但是 Eclipse 声称:

> Type mismatch: cannot convert from Object to Iterable<? extends
> Object>    
> Type mismatch: cannot convert from Seq<Object> to
> Seq<Tuple2<ScenState,Probability>>

一样,这可能归结为 Eclipse 编译器和 javac 之间的差异,问题可能可以通过在正确位置的类型见证来解决。为了找到合适的位置,我将从分解函数式方法链并提取一些局部变量开始:

Seq<Tuple2<ScenState, Probability>> result =
  resultStateProbs.flatMap(tuple -> {
    Seq<Tuple2<ScenState, Probability>> filteredAndUpdated =
      tuple.apply((spv, baTargetCount) -> {
        Seq<StateProbability> stateProbList = spv.getStateProbList();

        stateProbList.peek(sp -> {
          logger.debug("Checking if {} > {}: {}", sp.getProbability(), intermediateMinProb, sp.getProbability().greaterThan(intermediateMinProb));
        });

        Seq<StateProbability> filtered = stateProbList.filter(sp ->
          sp.getProbability().greaterThan(intermediateMinProb));

        Seq<Tuple2<ScenState, Probability>> updated = filtered.map(sp ->
          updateScenarioData(sp, baTargetCount, dupStateInfo));

        return updated;
      });
    return filteredAndUpdated;
  });

如果您使用 Eclipse 的提取变量重构,它本身可能会告诉您它在哪里推断出错误的类型,并且显式声明局部变量的正确类型可能足以自行解决问题。

如果不是,它至少应该缩小错误范围,并向您准确显示 Eclipse 在调用链中的哪个位置出现问题。然后你可以用类型见证来修复它,或者,如果所有其他方法都失败了,显式转换,然后(添加了该类型信息)也许再次内联变量,尽管这段代码足够密集,我可能会把它们留在里面。


旁注:

  1. peek() 只会调试第一个 StateProbability -- 这是你的意图吗?
  2. 考虑向 StateProbability 添加一个 greaterThan() 方法,这样您就不必重复调用 getProbability().greaterThan()。 (如果 #1 的答案是 "no",这个方法也是放置调试语句的好地方。)
  3. 考虑在 SceneState 上添加一个 return 预过滤列表的方法,例如 Seq<StateProbability> SceneState.allGreaterThan(Probability).