java - 这个注释是在数组上还是在数组的元素类型上?
问题描述
看看这个简单的代码。
try (@Foo Stream<@Bar Baz> foo = blabla) { }
我们知道@Bar
是 annotating Baz
,并且@Foo
是 annotating Stream
(我这里写了一个类似的例子,在线编译!)。
但是这段代码呢?
void whatever(@Foo String[] args) { }
这里我们有一个String[]
注解@Foo
(不管注解是什么,对这个问题都不重要)。
我的问题是,是否在or上进行@Foo
了注释?String
String[]
确定注解的目标非常重要,因为有时我们使用注解@NotNull
来表示一种类型的可空性,这@NotNull List<String>
意味着一个从不为空的列表包含一些可能为空的字符串;List<@NotNull String>
表示一个可能为 null 但成员绝不为 null 的列表。
一个可能的用例:我需要一个@NotNull
来显示args
不为空,另一个@NotNull
来显示成员args
也不为空?我需要同时注释它们。如果args
是java.util.List
,我可以使用@NotNull List<@NotNull String>
. 但是args
是一个数组——我不知道注释如何影响args
.
解决方案
在数组级别之前定义@NonNull
似乎可以解决问题(至少对于 Checker Framework):
import org.checkerframework.checker.nullness.qual.NonNull;
class App {
void foo() {
String @NonNull [] bar;
bar = null; // NOK
bar = new String[1];
bar[0] = null; // NOK
}
}
导致两个错误(参见现场演示):
| No. | Type | Description | Line | Column |
|-----|-------|-----------------------------------------------------------------------------|------|--------|
| 1 | error | Error: [assignment.type.incompatible] incompatible types in assignment. | 6 | 15 |
| | | found : null | | |
| | | required: @Initialized @NonNull String @UnknownInitialization @NonNull [] | | |
| 2 | error | Error: [assignment.type.incompatible] incompatible types in assignment. | 8 | 18 |
| | | found : null | | |
| | | required: @Initialized @NonNull String | | |
要回答您的实际问题,请参阅规范 §9.7.4:
@C int @A [] @B [] f;
@A
适用于数组类型int[][]
,@B
适用于其组件类型int[]
,并@C
适用于元素类型int
。
所以@Foo String[] args
实际上是注释String
(读作:一个可能为空的非空字符串数组)。
推荐阅读
- angular - Angular 8下拉所选项目未在页面加载时显示
- c# - libgit2sharp Credentialsprovider 的 C# 代码的 VB.NET 等效项
- c - TMS320F28379D 闪存扇区存储常量
- java - 参数化类型的 Java 类型推断,例如 List
- c# - 如何在 xmarine android c# App 中显示内部存储自定义文件夹中的 pdf?
- python - 如何在不实例化类的情况下打印类变量的值?
- nginx - Nginx 重写不会改变浏览器中的 url
- javascript - Nodejs使用静态路由
- python - 重新索引时间序列数据
- amazon-web-services - 使用 Docker 在 AWS EC2 上运行 Elasticsearch