org.jetbrains.annotations.NotNull

public static void func(Foo.Bar.@NotNull Baz arg0) {

}


public static void func(@NotNull Foo.Bar.Baz arg0) {

}


public static void func(@NotNull Foo.Bar.@NotNull Baz arg0) {

}


Jaka jest różnica między podejściami adnotacji na temat parametru typu klasy zagnieżdżonej?

Który jest zalecany?

1
Cbdy 23 październik 2020, 09:46

1 odpowiedź

Najlepsza odpowiedź

Są one tylko jednostki syntaktyczne. Semantycznie, wszystkie oznaczają "Ten parametr nie powinien być null", i praktycznie wszystkie trzy kompiluje do tego samego wyboru zerowy w parametrze.

Powodem, dla którego wszystkie trzy prace są dlatego, że NotNull ma ElementType TYPE_USE, dzięki czemu możesz adnotyzować dowolne "typ użycia" z NotNull. Cóż, Bar w Foo.Bar jest użyciem typu Bar, dzięki czemu można adnotować, co robisz Foo.@NotNull Bar.

To podnosi pytanie, dlaczego NotNull ma w pierwszej kolejności ElementType.TYPE_USE. Na pewno nie pozwala Ci mieć 3 sposoby mówienia dokładnie tej samej rzeczy. Bardziej prawdopodobnym powodem jest pozwolenie na to zrobić:

List<@NotNull String> listWithNotNullElements;

W każdym razie wszystkie trzy z tych kompilacji do tego samego kodu bajtu, jak we wszystkich 3 przypadkach, NotNull jest adnotacyjnie parametr .

Wszystkie trzy z poniższych:

package io.github.sweeper777;
import org.jetbrains.annotations.NotNull;
public class Main {
    public static void main(String[] args) {
    }
    public void f( Foo.@NotNull Bar x) {
    }
}
class Foo {
    static class Bar {
    }
}
package io.github.sweeper777;
import org.jetbrains.annotations.NotNull;
public class Main {
    public static void main(String[] args) {
    }
    public void f(@NotNull Foo.@NotNull Bar x) {
    }
}
class Foo {
    static class Bar {
    }
}
package io.github.sweeper777;
import org.jetbrains.annotations.NotNull;
public class Main {
    public static void main(String[] args) {
    }
    public void f(@NotNull Foo.Bar x) {
    }
}
class Foo {
    static class Bar {
    }
}

Kompiluje się do:

Compiled from "Main.java"
public class io.github.sweeper777.Main {
  public io.github.sweeper777.Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: return

  public void f(io.github.sweeper777.Foo$Bar);
    Code:
       0: aload_1
       1: ifnonnull     8
       4: iconst_0
       5: invokestatic  #36                 // Method $$$reportNull$$$0:(I)V
       8: return

  private static void $$$reportNull$$$0(int);
    Code:
       0: ldc           #38                 // String Argument for @NotNull parameter \'%s\' of %s.%s must not be null
       2: iconst_3
       3: anewarray     #2                  // class java/lang/Object
       6: dup
       7: iconst_0
       8: ldc           #39                 // String x
      10: aastore
      11: dup
      12: iconst_1
      13: ldc           #40                 // String io/github/sweeper777/Main
      15: aastore
      16: dup
      17: iconst_2
      18: ldc           #41                 // String f
      20: aastore
      21: invokestatic  #47                 // Method java/lang/String.format:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
      24: new           #49                 // class java/lang/IllegalArgumentException
      27: dup_x1
      28: swap
      29: invokespecial #52                 // Method java/lang/IllegalArgumentException."<init>":(Ljava/lang/String;)V
      32: athrow
}
2
Sweeper 23 październik 2020, 07:27