简体   繁体   English

java.util.@Nullable是什么意思?

[英]What's the meaning of java.util.@Nullable?

I'm reading the code of Guava where I found the annotation java.util.@Nullable in some code.我正在阅读Guava 的代码,其中在某些代码中找到了注释java.util.@Nullable I know the meaning of @Nullable , but I don't understand this one.我知道@Nullable的含义,但我不明白这个。 In particular, I can't find a class called Nullable in the package java.util .特别是,我在 package java.util 中找不到名为Nullablejava.util Please, someone tell me what's the meaning of this java.util.@Nullable :请有人告诉我这个java.util.@Nullable是什么意思:

public static <T> java.util.@Nullable Optional<T> toJavaUtil(
    @Nullable Optional<T> googleOptional) {
  return googleOptional == null ? null : googleOptional.toJavaUtil();
}

The line public static <T> java.util.@Nullable Optional<T> toJavaUtil is written like this, because the usual style public static <T> @Nullable java.util.Optional<T> toJavaUtil is invalid. The line public static <T> java.util.@Nullable Optional<T> toJavaUtil is written like this, because the usual style public static <T> @Nullable java.util.Optional<T> toJavaUtil is invalid. This is defined in the JLS §9.7.4 :这是在JLS §9.7.4中定义的:

It is a compile-time error if an annotation of type T applies to a type (or any part of a type) in a type context, and T is applicable in type contexts, and the annotation is not admissible.如果类型 T 的注释适用于类型上下文中的类型(或类型的任何部分),并且 T 适用于类型上下文,并且该注释是不可接受的,则这是编译时错误。

For example, assume an annotation type TA which is meta-annotated with just @Target(ElementType.TYPE_USE) .例如,假设注释类型 TA 仅使用@Target(ElementType.TYPE_USE)进行元注释。 The terms @TA java.lang.Object and java.@TA lang.Object are illegal because the simple name to which @TA is closest is classified as a package name. The terms @TA java.lang.Object and java.@TA lang.Object are illegal because the simple name to which @TA is closest is classified as a package name. On the other hand, java.lang.@TA Object is legal.另一方面, java.lang.@TA Object是合法的。

The type declaration of org.checkerframework.checker.nullness.qual@Nullable is: org.checkerframework.checker.nullness.qual@Nullable的类型声明为:

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

So it is applying to this rule.所以它适用于这个规则。

That this structure doesn't break the execution, since package java.util and class name Optional were split, can be seen when we look at the compiled code using javap -c [compiled class name] : That this structure doesn't break the execution, since package java.util and class name Optional were split, can be seen when we look at the compiled code using javap -c [compiled class name] :

class just.a.test.Main {
  just.a.test.Main();
    Code:
       0: aload_0
       1: invokespecial #1          // Method java/lang/Object."<init>":()V
       4: return

  public static <T> java.util.Optional<T> toJavaUtil(blub.Optional<T>);
    Code:
       0: aload_0
       1: ifnonnull     8
       4: aconst_null
       5: goto          12
       8: aload_0
       9: invokevirtual #2          // Method blub/Optional.toJavaUtil:()Ljava/util/Optional;
      12: areturn
}

( blub.Optional is a local class where I copied the Guava code in, in order to get a minimal example to de-/compile) blub.Optional是一个本地 class ,我在其中复制了番石榴代码,以获得一个最小的示例来反编译)

As you can see, the annotation doesn't exist there anymore.如您所见,注释不再存在。 It is only a marker for the compiler to prevent a warning when the method returns null (and a hint for the source code readers), but it won't be included in the compiled code.它只是编译器在方法返回 null 时防止警告的标记(以及对源代码阅读器的提示),但它不会包含在编译代码中。


This compiler error also applies to variables like:此编译器错误也适用于以下变量:

private @Nullable2 java.util.Optional<?> o;

But can become acceptable when the annotation additionally gets the target type ElementType.FIELD , as written in the same JLS clause:但是当注解另外获得目标类型ElementType.FIELD时可以变得可以接受,如在同一个 JLS 子句中所写:

If TA is additionally meta-annotated with @Target(ElementType.FIELD) , then the term @TA java.lang.Object is legal in locations which are both declaration and type contexts, such as a field declaration @TA java.lang.Object f; If TA is additionally meta-annotated with @Target(ElementType.FIELD) , then the term @TA java.lang.Object is legal in locations which are both declaration and type contexts, such as a field declaration @TA java.lang.Object f; . . Here, @TA is deemed to apply to the declaration of f (and not to the type java.lang.Object) because TA is applicable in the field declaration context.这里,@TA 被认为适用于 f 的声明(而不适用于类型 java.lang.Object),因为 TA 适用于字段声明上下文。

When using annotations, this is the syntax that is used when you want to write fully qualified name for the type, instead of adding import statement.使用注解时,这是当您要为类型编写完全限定名称而不是添加 import 语句时使用的语法。

Quoting from the checker framework manual :引用检查器框架手册

The correct Java syntax to write an annotation on a fully-qualified type name is to put the annotation on the simple name part, as in java.util.@Nullable List.在完全限定类型名称上编写注释的正确 Java 语法是将注释放在简单名称部分,如 java.util.@Nullable List。 But, it's usually better to add import java.util.List to your source file, so that you can just write @Nullable List.但是,通常最好将 import java.util.List 添加到您的源文件中,这样您就可以只写@Nullable List。

It is also mentioned on page 2 of JSR308 specification which can be downloaded here . JSR308规范的第 2 页也提到了它,可以在这里下载。 It says:它说:

A type annotation appears before the type's simple name, as in @NonNull String or java.lang.@NonNull String.类型注释出现在类型的简单名称之前,如 @NonNull 字符串或 java.lang.@NonNull 字符串。

The strange bit here really is the unfamiliar syntax for applying a ElementType.TYPE_USE -targeted annotation.这里的奇怪之处确实是应用ElementType.TYPE_USE目标注解的不熟悉语法。 If you check the Nullable 's docs, you'll see the unfamiliar target:如果您查看Nullable的文档,您会看到不熟悉的目标:

...
@Target(value={TYPE_USE,TYPE_PARAMETER})
<public @interface Nullable
...

This annotation is used right before the simple name of the annotated type, like in both of the following:此注解在被注解类型的简单名称之前使用,如下面的两个:

public static <T> @Nullable Optional<T> toJavaUtil
public static <T> java.util.@Nullable Optional<T> toJavaUtil

I didn't know what the use of this kind of target was, so after a quick read, I got to this simple example, which picks up return type metadata using an annotation that has that target:我不知道这种目标的用途是什么,所以在快速阅读之后,我得到了这个简单的示例,它使用具有该目标的注释来获取返回类型元数据:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@interface InterceptedReturnValue {
    boolean value() default true;
}

And processed it using:并使用以下方法处理它:

public java.lang.@InterceptedReturnValue(true) String testMethod(String param) {
    return null;
}

public @InterceptedReturnValue(false) String testMethod(int param) {
    return null;
}

public static void main(String[] args) throws Exception {
    Method m = Main.class.getDeclaredMethod("testMethod", String.class);
    if(m.getAnnotatedReturnType().isAnnotationPresent(InterceptedReturnValue.class)) {
        InterceptedReturnValue config = m.getAnnotatedReturnType()
                .getAnnotation(InterceptedReturnValue.class);

        if(config.value()) {
            //logging return value enabled
        }
    }
}

I'm sure many useful frameworks, such as checkerframework, make the most appropriate use of ElementType.TYPE_USE我确信许多有用的框架,例如 checkerframework,都最恰当地使用了ElementType.TYPE_USE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 @Nullable java的意思(android) - Meaning of @Nullable java (android) 在Java中打印线程实例的意义是什么? - What's the meaning of printing a thread instance in Java? Java:这个类HashMap方法的含义是什么? - Java: what's the meaning of this method of class HashMap? Java的Enum声明是什么意思? - What is the meaning of the Java's Enum declaration? 这种Java泛型的用法是什么意思? - What's the meaning of this usage of Java generics? java.util.Stack 有什么问题? - What's wrong with java.util.Stack? JavaBean的getter / setter实现中可空的java.util.Date的“防御性复制”的优雅实现示例? - Example of an elegant implementation of 'Defensive Copying' of a nullable java.util.Date in a JavaBean's getter/setter implementation? 这个错误是什么意思“java.util.stream.ReferencePipeline$3 不能转换为 org.springframework.data.domain.Page” - what meaning this error “java.util.stream.ReferencePipeline$3 cannot be cast to org.springframework.data.domain.Page” Java中对象监视器的含义是什么? 为什么要用这个词? - What's the meaning of an object's monitor in Java? Why use this word? Java 的 java/util/function/BiFunction 的 C# 是什么? - What is the C# equivalent of Java's java/util/function/BiFunction?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM