【问题标题】:Valid annotation for parent is invalid for child父母的有效注释对孩子无效
【发布时间】:2019-06-26 21:30:13
【问题描述】:

您好,我的父类带有可空注释的参数。

class Parent {

  @Nullable
  String name;

  Parent(@Nullable Strign name) {
    this.name = name;
  }

  Driver createDriver() {
    return new CommonDriver(name);
  }
}

我有多个子类,对于大多数子类,“name”参数可以为空,但有些不能。

class ChildC extends Parent {

  ChildC(@NotNull String name){
    super(name);
  }

  @Override
  Driver createDriver() {
    return new ChildCDriver(name);
  }
}

现在我在 ChildCDriver 中遇到问题(来自 intelliJ 的代码检查),其中名称为 @NotNull

这个问题能解决吗?

【问题讨论】:

  • 子类的意义何在?它共享一个字段,否则会覆盖行为的所有其他方面。只需让父母和孩子成为一个公共接口的 2 个实现。这里不需要继承。
  • 我首先误读了您的问题,因此是错误的,现在已删除答案。想知道:“我有问题”是什么意思?如果有错误消息,请在您的问题中包含它!
  • @Michael 这是简化的例子。关键是在父范围内参数可以为空,但在子范围内不能。
  • @GhostCat 为什么我们使用 Nullable 和 NotNull 注释?让我们的 IDE 警告我们出现问题。至少我会。现在我收到无效的警告。此外,我的代码审查员总是对任何警告都很着迷。
  • @LukasHanacek 压制它

标签: java annotations nullable


【解决方案1】:

这是合理的代码,但 IntelliJ 并不足以证明代码是正确的。您需要抑制警告。单击该行,按Alt+Enter,然后在该菜单或子菜单中找到“Suppress”。

Nullness Checker 可以验证您的代码。完整的代码如下所示。 @FieldInvariant 注解表示字段has a more precise type in the subclass

如果没有 @FieldInvariant 注释,Nullness Checker 会在第 27 行发出此警告:

error: [argument.type.incompatible] incompatible types in argument.
    return new ChildCDriver(name);
                            ^
  found   : @Initialized @Nullable String
  required: @Initialized @NonNull String

使用@FieldInvariant 注释,Nullness Checker 证明代码是正确的。

以下代码示例使用 Checker Framework 的 @NonNull@Nullable 注释,但使用 Nullness Checker also supports @NotNull,因此您可以继续在代码中使用 JetBrains 注释。

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.qual.FieldInvariant;

class Parent {

  final @Nullable String name;

  Parent(@Nullable String name) {
    this.name = name;
  }

  Driver createDriver() {
    return new CommonDriver(name);
  }
}

@FieldInvariant(qualifier = NonNull.class, field = "name")
class ChildC extends Parent {

  ChildC(@NonNull String name) {
    super(name);
  }

  @Override
  Driver createDriver() {
    return new ChildCDriver(name);
  }
}

interface Driver {}

class CommonDriver implements Driver {
  CommonDriver(@Nullable String name) {}
}

class ChildCDriver implements Driver {
  ChildCDriver(@NonNull String name) {}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-12
    • 2021-10-17
    相关资源
    最近更新 更多