我想提供一些值容器的访问器(即引擎盖下的java.lang.Map).

当实现这样的访问器时

public Optional<Integer> getSomeValueThatMayBeNullOrAnInteger() {
    Integer nullable = this.get("keyToANullableInteger", Integer.class); // is casting to given Class
    return Optional.ofNullable(nullable);
}

... '"ofNullable"标记为"unsafe null type convertion".

为什么会这样?unlable参数未标记为@NonNull.

请有人向我解释一下,也许可以告诉我,如果有其他方法可以解决这个警告使用@SuppressWarnings("null").谢谢

推荐答案

java core中缺少nullity注释

每种类型都有一个空状态.因此,在Optional<Integer>中,提到的两种类型都具有空状态-是@NonNull Optional<@NonNull Integer>吗?大概答案很简单:是的.

有一个"nullable optional"(如果有,请先停止并修复),并且optional的typearg为@NonNull(不能有值为null的optional.SOME).

然而,eclipse doesn't know that.此外,java核心类are not nullity annotated.

想必,您已经将类标记为"default to-everything is nonnull-",否则您需要对所有笨拙的对象加@NonNull.因此,eclipse认为方法的返回类型是@NonNull Optional<@NonNull Integer>.

然而,Optional.ofNullable方法(在类java.util.Optional中)只返回@WhoKnows Optional<@WhoKnows T>-j.u.Optional类没有标记为"默认为所有非空",方法本身也没有用@NonNull注释,因为java核心类根本没有这样的注释.因此,eclipse正在警告您,告诉您:嘿,Optional.ofNullable可能返回null(我们知道不会,但eclipse怎么会知道呢?),您只是逐字返回,但your方法promise 永远不会返回null,所以这是一个潜在的问题.

如何使用nullity批注

您有一种方法可以让空值判断器(在您的例子中是eclipse)知道everything的空值状态.包括您正在使用的库,所以至少包括java.*个.这意味着您需要一个称为"外部注释"的概念,可以说,这个文件"填补了java.*和其他所有内容的空白".首先,它会列出java.util.Optional中的ofNullable静态方法应该被视为用@NonNull注释.

如果没有这样一个系统,这将是一个悲惨的、悲惨的经历——在无效注释上走到一半,意味着你将得到无休止的警告.这会导致您删除警告(这会使功能变得毫无意义)或用@SuppressWarnings("null")注释大多数方法,这也会使功能变得毫无意义.

我上一次判断是在很久以前,当时没有这样的文件或系统可用,但我相信eclipse至少添加了"外部注释"的概念.我会搜索web并try 查找包含所有/大部分java的EA文件.*API,并使用它.

Select 一边!

Optional是将空状态提升到类型系统中的一种方法.

注释也是一种方法.

不要同时使用两者.

关于无效系统的有用事实

  • Optional不向后兼容.以java.util.Map.get()法为例.它当前返回V.如果您认为正确答案是可选的,那么这个方法是不正确的,因为它应该返回Optional<V>.然而,更改它是向后不兼容的,java极不可能做到这一点.因此,Optional will never到达了他们的完美世界,在那里,Optional到处都被用作事实上的机制.
  • 注释可以向后兼容,因此作为一个答案,它显然更优越.不幸的是,至少有9个相互竞争的基于注释的空值系统,它们的工作方式完全不同.例如,有些是基于类型使用的,有些不是.
  • 大多数基于注释的框架没有@PolyNull概念(只有checkerframework有).这意味着它们都无法表示某些现有方法的空状态.
  • Optional不能正确组合,没有poly null概念,也不能使其具有poly null,因此这是Optional永远无法在java中完全替换null的另一个原因.

你还剩下什么

Nullity注释非常笨拙(未标准化,缺少外部注释文件).Optional是一个白日梦(不能修改现有的API来使用它).那你现在的处境如何?

大多数情况下,只要接受null就可以了.关闭基于注释的判断,停止对此类内容使用Optional.

您现在可以做一些事情,而且java API已经在做一些事情,因为它完全向后兼容:

_Work on nicer APIs.

例如,看看java.util.Map的javadoc.有computeIfAbsentgetOrDefault和其他一些方法,它们主要意味着您不需要任何基于类型的空值就可以使用Map,而无需使用null.例如,您不必编写以下代码:

Map<String, List<String>> example = ...;

List<String> list = example.get(key);
if (list == null) {
  list = new ArrayList<>();
  example.put(key, list);
}
list.add("Test");

相反,您可以只写:

Map<String, List<String>> example = ...;

example.computeIfAbsent(key, k -> new ArrayList<>()).add("Test");

你不必写:

Map<String, Integer> example = ...;

int v = 0;
// 2 calls - ugly
if (example.containsKey(key)) v = example.get(key);
// or:
Integer vRaw = example.get(key);
if (vRaw != null) v = vRaw.intValue();

您可以只写:

Map<String, Integer> example = ...;

int v = example.getOrDefault(key, 0);

您可以将相同的原则应用于所编写的代码.例如:

public int getSomeValue(int defaultValue) {
  Integer nullable = this.get("keyToANullableInteger", Integer.class);
  return nullable == null ? defaultValue : nullable.intValue();
}

public Integer getSomeValueOrNull() {
  return this.get("keyToANullableInteger", Integer.class);
}

public int getSomeValue() {
  Integer n = this.get("keyToANullableInteger", Integer.class);
  if (n == null) throw new NullPointerException("key not present in data store");
  return n.intValue();
}

调用者不可能对此处可以和不可以为null的内容感到困惑.(您可能不需要全部3个,请考虑一下您的API设计).

Java相关问答推荐

在URL类图中表示Java swing类

基于仅存在于父级中的字段查询子文档?

Java应用程序崩溃时试图读取联系人从电话

JPackaged应用程序启动MSI调试,然后启动System. exit()

使用java访问具体子类特定方法的最佳方法是什么?

无法在org. openjfx:javafx—fxml:21的下列变体之间进行 Select

Java记录的不同序列化/反序列化

如何判断一个矩阵是否为有框矩阵?

呈现文本和四舍五入矩形时出现的JavaFX窗格白色瑕疵

GSON期间的Java类型擦除

Bean定义不是从Spring ApplationConext.xml文件加载的

我正在try 跟踪数组中最大的两个数字

允许同时执行两个方法,但不能同时执行这两个方法

来自外部模块的方面(对于Java+Gradle项目)不起作用

使用SWIG将C++自定义单元类型转换为基本Java类型

在Spring Boot JPA for MySQL中为我的所有类创建Bean时出错?

在缺少字段时使用Jackson With Options生成Optional.Empty()

如果c不为null,Arrays.sort(T[]a,Comparator<;?super T>;c)是否会引发ClassCastException?

URI构造函数错误?

以较小的时间复杂度找到最大值的最小值