在 FunctionalInterface lambda 中处理 @Nullable
Dealing with @Nullable in FunctionalInterface lambda
我应该如何使用 checker-framework 类型注释处理 lambda 函数?
例如,
private void dispatch(Progress progress, Load request, @Nullable Layer layer)
{
if (layer == null) return;
Utils.log("DISPATCHING " + layer.name);
JThread.run(() -> runDispatch(progress, request, layer));
}
Checker 将在 runDispatch
线路调用上发出 argument.type.incompatible
警告,即使事先已检查 layer
。我知道 lambda 函数在不同的上下文中,因此 Checker 无法正确评估它。最好的处理方法是什么?
额外信息
完全警告:
error: [argument.type.incompatible] incompatible types in argument.
[ERROR] found : @Initialized @Nullable Layer<? extends @Initialized @NonNull Item, ? extends @Initialized @NonNull Deliver, ? extends @Initialized @NonNull Recipient>
[ERROR]
[ERROR] required: @Initialized @NonNull Layer<? extends @Initialized @NonNull Item, ? extends @Initialized @NonNull Deliver, ? extends @Initialized @NonNull Recipient>
runDispatch
声明在同一个class,签名private void runDispatch(Progress progress, Load request, Layer layer)
另一个例子:
在我的代码的其他地方我有类似的情况,但涉及方法行为:
在 Item.class
上:
@EnsuresNonNullIf(expression="extraAction", result=true)
public final boolean hasExtraAction() {
return extraAction != null;
}
单独 class:
@RequiresNonNull("#2.extraAction")
private void buildExtraActionRunnable(Layer layer, Item item, Deliver deliver) {
....
}
...
} else if (item.hasExtraAction()) {
Runnable r = () -> buildExtraActionRunnable(layer, item, deliver);
在这里,在 Runnable 行我得到 error: [contracts.precondition.not.satisfied] the called method 'buildExtraActionRunnable(layer, item, deliver)' has a precondition 'item.extraAction' that is not satisfied
我同意这是 bug in the Nullness Checker。
在这部分代码中:
Utils.log("DISPATCHING " + layer.name);
JThread.run(() -> runDispatch(progress, request, layer));
Nullness Checker 在 Utils.log
的调用中知道 layer
是非空的,但在方法体内调用 runDispatch
时它不知道这个事实.在方法体内,它使用 declared 类型 layer
而不是通过数据流分析计算的 refined 类型。
您的问题是如何解决 Checker Framework 错误。
一种方法是引入一个新变量:
Utils.log("DISPATCHING " + layer.name);
Layer layer2 = layer; // work around CF issue #1248
JThread.run(() -> runDispatch(progress, request, layer2));
以上代码类型检查正确。
你的第二个例子我无法给出详细的答案,因为你没有给出可编译的MWE。但是每当出现 error: [KEY] ...
形式的错误时,您总是可以通过添加 @SuppressWarnings("KEY")
来抑制它。根据您的情况,这将是 @SuppressWarnings("contracts.precondition.not.satisfied")
.
我应该如何使用 checker-framework 类型注释处理 lambda 函数?
例如,
private void dispatch(Progress progress, Load request, @Nullable Layer layer)
{
if (layer == null) return;
Utils.log("DISPATCHING " + layer.name);
JThread.run(() -> runDispatch(progress, request, layer));
}
Checker 将在 runDispatch
线路调用上发出 argument.type.incompatible
警告,即使事先已检查 layer
。我知道 lambda 函数在不同的上下文中,因此 Checker 无法正确评估它。最好的处理方法是什么?
额外信息
完全警告:
error: [argument.type.incompatible] incompatible types in argument.
[ERROR] found : @Initialized @Nullable Layer<? extends @Initialized @NonNull Item, ? extends @Initialized @NonNull Deliver, ? extends @Initialized @NonNull Recipient>
[ERROR]
[ERROR] required: @Initialized @NonNull Layer<? extends @Initialized @NonNull Item, ? extends @Initialized @NonNull Deliver, ? extends @Initialized @NonNull Recipient>
runDispatch
声明在同一个class,签名private void runDispatch(Progress progress, Load request, Layer layer)
另一个例子: 在我的代码的其他地方我有类似的情况,但涉及方法行为:
在 Item.class
上:
@EnsuresNonNullIf(expression="extraAction", result=true)
public final boolean hasExtraAction() {
return extraAction != null;
}
单独 class:
@RequiresNonNull("#2.extraAction")
private void buildExtraActionRunnable(Layer layer, Item item, Deliver deliver) {
....
}
...
} else if (item.hasExtraAction()) {
Runnable r = () -> buildExtraActionRunnable(layer, item, deliver);
在这里,在 Runnable 行我得到 error: [contracts.precondition.not.satisfied] the called method 'buildExtraActionRunnable(layer, item, deliver)' has a precondition 'item.extraAction' that is not satisfied
我同意这是 bug in the Nullness Checker。 在这部分代码中:
Utils.log("DISPATCHING " + layer.name);
JThread.run(() -> runDispatch(progress, request, layer));
Nullness Checker 在 Utils.log
的调用中知道 layer
是非空的,但在方法体内调用 runDispatch
时它不知道这个事实.在方法体内,它使用 declared 类型 layer
而不是通过数据流分析计算的 refined 类型。
您的问题是如何解决 Checker Framework 错误。 一种方法是引入一个新变量:
Utils.log("DISPATCHING " + layer.name);
Layer layer2 = layer; // work around CF issue #1248
JThread.run(() -> runDispatch(progress, request, layer2));
以上代码类型检查正确。
你的第二个例子我无法给出详细的答案,因为你没有给出可编译的MWE。但是每当出现 error: [KEY] ...
形式的错误时,您总是可以通过添加 @SuppressWarnings("KEY")
来抑制它。根据您的情况,这将是 @SuppressWarnings("contracts.precondition.not.satisfied")
.