Anotasi @NotNull Java manakah yang harus saya gunakan?


999

Saya ingin membuat kode saya lebih mudah dibaca serta menggunakan perkakas seperti inspeksi kode IDE dan / atau analisis kode statis (FindBugs dan Sonar) untuk menghindari NullPointerExceptions. Banyak alat yang tampaknya tidak kompatibel satu sama lain @NotNull/ @NonNull/ @Nonnullanotasi dan daftar semuanya dalam kode saya akan mengerikan untuk dibaca. Adakah saran yang mana yang 'terbaik'? Berikut adalah daftar penjelasan yang setara yang saya temukan:

  • javax.validation.constraints.NotNull
    Dibuat untuk validasi runtime, bukan analisis statis.
    dokumentasi

  • edu.umd.cs.findbugs.annotations.NonNull
    Digunakan oleh analisis statis Findbugs dan karenanya dokumentasi Sonar (sekarang Sonarqube )

  • javax.annotation.Nonnull
    Ini mungkin bekerja dengan Findbugs juga, tetapi JSR-305 tidak aktif. (Lihat juga: Apa status JSR 305? ) Sumber

  • org.jetbrains.annotations.NotNull
    Digunakan oleh IntelliJ IDEA IDE untuk analisis statis.
    dokumentasi

  • lombok.NonNull
    Digunakan untuk mengontrol pembuatan kode di Proyek Lombok .
    Anotasi Placeholder karena tidak ada standar.
    sumber , dokumentasi

  • android.support.annotation.NonNull
    Anotasi penanda tersedia di Android, disediakan oleh dokumentasi paket anotasi dukungan

  • org.eclipse.jdt.annotation.NonNull
    Digunakan oleh Eclipse untuk dokumentasi analisis kode statis


203
apache harus membuat anotasi "umum" dan alat yang dapat mengubahnya menjadi anotasi lainnya. solusi untuk masalah terlalu banyak standar adalah menciptakan standar baru.
diperbaiki

6
@Reputable jika apache menciptakan "common" baru, akan ada 56 versi, yang tumpang tindih dengan proyek lain. Dan, itu tidak akan menjadi standar (standar! = Luas). Lebih baik menggunakan sesuatu yang benar-benar standar, javax?. *. BTW, tidak ada "terlalu banyak standar" dalam contoh-contoh itu, saya hanya melihat 1 atau 2.
ymajoros

6
javax.annotation.Nonnull tidak bekerja dengan findbugs (baru mengujinya), yang merupakan alasan kuat bagi saya untuk menggunakannya.
Nicolas C

20
Jika saya cukup menulis @NotNull, itu merujuk ke com.sun.istack.internal.NotNull. OMG ...
Thomas Weller

3
@MozartBrocchini - Opsional berguna dalam kasus di mana Anda mungkin sebelumnya menggunakan NullObjects. Mereka tidak benar-benar membahas tujuan yang sama dengan runtime \ @NotNull annotation, dan mereka memperkenalkan bungkusan yang membosankan.
Dave

Jawaban:


205

Sejak JSR 305 (yang tujuannya adalah untuk membakukan @NonNulldan @Nullable) telah aktif selama beberapa tahun, saya khawatir tidak ada jawaban yang baik. Yang bisa kita lakukan adalah menemukan solusi pragmatis dan milikku adalah sebagai berikut:

Sintaksis

Dari sudut pandang gaya murni, saya ingin menghindari referensi ke IDE, framework atau toolkit apa pun kecuali Java itu sendiri.

Ini mengesampingkan:

  • android.support.annotation
  • edu.umd.cs.findbugs.annotations
  • org.eclipse.jdt.annotation
  • org.jetbrains.annotations
  • org.checkerframework.checker.nullness.qual
  • lombok.NonNull

Yang membuat kita salah javax.validation.constraintsatau javax.annotation. Yang pertama dilengkapi dengan JEE. Jika ini lebih baik daripada javax.annotation, yang mungkin datang bersama BEJ atau tidak pernah sama sekali, adalah masalah perdebatan. Saya pribadi lebih suka javax.annotationkarena saya tidak suka ketergantungan JEE.

Ini meninggalkan kita

javax.annotation

yang juga merupakan yang terpendek.

Hanya ada satu sintaks yang bahkan akan lebih baik: java.annotation.Nullable. Ketika paket-paket lain lulus dari javaxke javamasa lalu, javax.annotation akan menjadi langkah ke arah yang benar.

Penerapan

Saya berharap bahwa mereka semua pada dasarnya memiliki implementasi sepele yang sama, tetapi analisis rinci menunjukkan bahwa ini tidak benar.

Pertama untuk kesamaan:

Semua @NonNullanotasi memiliki garis

public @interface NonNull {}

kecuali untuk

  • org.jetbrains.annotationsyang menyebutnya @NotNulldan memiliki implementasi yang sepele
  • javax.annotation yang memiliki implementasi lebih lama
  • javax.validation.constraintsyang juga menyebutnya @NotNulldan memiliki implementasi

Semua @Nullableanotasi memiliki garis

public @interface Nullable {}

kecuali untuk (lagi) org.jetbrains.annotationsdengan implementasi sepele mereka.

Untuk perbedaan:

Yang mengejutkan adalah itu

  • javax.annotation
  • javax.validation.constraints
  • org.checkerframework.checker.nullness.qual

semua memiliki anotasi runtime ( @Retention(RUNTIME)), sementara

  • android.support.annotation
  • edu.umd.cs.findbugs.annotations
  • org.eclipse.jdt.annotation
  • org.jetbrains.annotations

hanya waktu kompilasi ( @Retention(CLASS)).

Seperti yang dijelaskan dalam jawaban SO ini dampak anotasi runtime lebih kecil daripada yang mungkin dipikirkan orang, tetapi mereka memiliki manfaat mengaktifkan alat untuk melakukan pemeriksaan runtime di samping waktu kompilasi.

Perbedaan penting lainnya adalah di mana dalam kode anotasi dapat digunakan. Ada dua pendekatan berbeda. Beberapa paket menggunakan konteks gaya JLS 9.6.4.1. Tabel berikut memberikan gambaran:

                                METODE PARAMETER BIDANG LOCAL_VARIABLE 
android.support.annotation XXX   
edu.umd.cs.findbugs.annotations XXXX
org.jetbrains.annotation XXXX
lombok XXXX
javax.validation.constraints XXX   

org.eclipse.jdt.annotation, javax.annotationdan org.checkerframework.checker.nullness.qualgunakan konteks yang didefinisikan dalam JLS 4.11, yang menurut saya cara yang tepat untuk melakukannya.

Ini meninggalkan kita

  • javax.annotation
  • org.checkerframework.checker.nullness.qual

di babak ini.

Kode

Untuk membantu Anda membandingkan detail lebih lanjut sendiri, saya mencantumkan kode setiap anotasi di bawah ini. Untuk memudahkan perbandingan, saya menghapus komentar, impor, dan @Documentedanotasi. (mereka semua memiliki @Documentedkecuali kelas dari paket Android). Saya memesan ulang garis dan @Targetbidang dan menormalkan kualifikasi.

package android.support.annotation;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER})
public @interface NonNull {}

package edu.umd.cs.findbugs.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NonNull {}

package org.eclipse.jdt.annotation;
@Retention(CLASS)
@Target({ TYPE_USE })
public @interface NonNull {}

package org.jetbrains.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NotNull {String value() default "";}

package javax.annotation;
@TypeQualifier
@Retention(RUNTIME)
public @interface Nonnull {
    When when() default When.ALWAYS;
    static class Checker implements TypeQualifierValidator<Nonnull> {
        public When forConstantValue(Nonnull qualifierqualifierArgument,
                Object value) {
            if (value == null)
                return When.NEVER;
            return When.ALWAYS;
        }
    }
}

package org.checkerframework.checker.nullness.qual;
@Retention(RUNTIME)
@Target({TYPE_USE, TYPE_PARAMETER})
@SubtypeOf(MonotonicNonNull.class)
@ImplicitFor(
    types = {
        TypeKind.PACKAGE,
        TypeKind.INT,
        TypeKind.BOOLEAN,
        TypeKind.CHAR,
        TypeKind.DOUBLE,
        TypeKind.FLOAT,
        TypeKind.LONG,
        TypeKind.SHORT,
        TypeKind.BYTE
    },
    literals = {LiteralKind.STRING}
)
@DefaultQualifierInHierarchy
@DefaultFor({TypeUseLocation.EXCEPTION_PARAMETER})
@DefaultInUncheckedCodeFor({TypeUseLocation.PARAMETER, TypeUseLocation.LOWER_BOUND})
public @interface NonNull {}

Untuk kelengkapan, berikut @Nullableimplementasinya:

package android.support.annotation;
@Retention(CLASS)
@Target({METHOD, PARAMETER, FIELD})
public @interface Nullable {}

package edu.umd.cs.findbugs.annotations;
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
@Retention(CLASS)
public @interface Nullable {}

package org.eclipse.jdt.annotation;
@Retention(CLASS)
@Target({ TYPE_USE })
public @interface Nullable {}

package org.jetbrains.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface Nullable {String value() default "";}

package javax.annotation;
@TypeQualifierNickname
@Nonnull(when = When.UNKNOWN)
@Retention(RUNTIME)
public @interface Nullable {}

package org.checkerframework.checker.nullness.qual;
@Retention(RUNTIME)
@Target({TYPE_USE, TYPE_PARAMETER})
@SubtypeOf({})
@ImplicitFor(
    literals = {LiteralKind.NULL},
    typeNames = {java.lang.Void.class}
)
@DefaultInUncheckedCodeFor({TypeUseLocation.RETURN, TypeUseLocation.UPPER_BOUND})
public @interface Nullable {}

Dua paket berikut tidak punya @Nullable, jadi saya daftar secara terpisah; Lombok memiliki hal yang cukup membosankan @NonNull. Di javax.validation.constraintsdalam @NonNullsebenarnya @NotNull dan memiliki implementasi gondrong.

package lombok;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NonNull {}

package javax.validation.constraints;
@Retention(RUNTIME)
@Target({ FIELD, METHOD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Constraint(validatedBy = {})
public @interface NotNull {
    String message() default "{javax.validation.constraints.NotNull.message}";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default {};
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        NotNull[] value();
    }
}

Dukung

Dari pengalaman saya, javax.annotationsetidaknya didukung oleh Eclipse dan Framework Checker di luar kotak.

Ringkasan

Anotasi ideal saya adalah java.annotationsintaks dengan implementasi Framework Checker.

Jika Anda tidak bermaksud menggunakan Kerangka Pemeriksa javax.annotation( JSR-305 ) masih merupakan taruhan terbaik Anda untuk saat ini.

Jika Anda bersedia untuk membeli Kerangka Pemeriksa gunakan saja org.checkerframework.checker.nullness.qual.


Sumber

  • android.support.annotation dari android-5.1.1_r1.jar
  • edu.umd.cs.findbugs.annotations dari findbugs-annotations-1.0.0.jar
  • org.eclipse.jdt.annotation dari org.eclipse.jdt.annotation_2.1.0.v20160418-1457.jar
  • org.jetbrains.annotations dari jetbrains-annotations-13.0.jar
  • javax.annotation dari gwt-dev-2.5.1-sources.jar
  • org.checkerframework.checker.nullness.qual dari checker-framework-2.1.9.zip
  • lombokdari lombokkomitf6da35e4c4f3305ecd1b415e2ab1b9ef8a9120b4
  • javax.validation.constraints dari validation-api-1.0.0.GA-sources.jar

7
Kelemahan dari javax.annotationini adalah: a) berdasarkan JSR mati, b) sulit menemukan artefak yang hanya menyediakan anotasi dan dipertahankan. Yang dari findbugs bukan: search.maven.org/…
robinst

18
Poin lain yang menentang javax.annotationadalah bahwa hal itu menyebabkan masalah dengan Java 9 karena modul lain juga menyediakan kelas dalam paket itu (jax-ws).
robinst

10
@kevinarpe: Proyek Findbugs sudah mati, dan proyek penerus Spotbugs menghapus anotasi tersebut: github.com/spotbugs/spotbugs/pull/180
robinst

4
JSR 305 , yang sudah terstandarisasi javax.annotation.NonNull, tidak pernah selesai karena lead specnya AWOL. Itu tidak ada hubungannya dengan keputusan apa pun oleh Oracle.
Mark Reinhold

5
Alasan lain untuk tidak menggunakan jsr305.jar adalah bahwa itu tampaknya melanggar lisensi biner Oracle Java: github.com/google/guava/issues/2960
Flow

91

Saya sangat menyukai Framework Checker , yang merupakan implementasi dari anotasi tipe ( JSR-308 ) yang digunakan untuk mengimplementasikan checker cacat seperti checker nullness. Saya belum benar-benar mencoba yang lain untuk menawarkan perbandingan, tetapi saya senang dengan implementasi ini.

Saya tidak berafiliasi dengan grup yang menawarkan perangkat lunak, tetapi saya penggemar.

Empat hal yang saya sukai dari sistem ini:

  1. Ini memiliki checker cacat untuk nullness (@Nullable), tetapi juga memiliki yang untuk kekekalan dan magang (dan lain-lain). Saya menggunakan yang pertama (nullness) dan saya mencoba menggunakan yang kedua (immutability / IGJ). Saya mencoba yang ketiga, tapi saya belum yakin menggunakannya dalam jangka panjang. Saya belum yakin akan kegunaan umum dari checker lain, tapi senang mengetahui bahwa framework itu sendiri adalah sebuah sistem untuk mengimplementasikan berbagai anotasi dan checker tambahan.

  2. The Pengaturan standar untuk memeriksa nullness bekerja dengan baik: Non-null kecuali penduduk setempat (nnel). Pada dasarnya ini berarti bahwa secara default pemeriksa memperlakukan everyhing (variabel instance, parameter metode, tipe generik, dll) kecuali variabel lokal seolah-olah mereka memiliki tipe @NonNull secara default. Per dokumentasi:

    Default NNEL mengarah ke jumlah terkecil dari anotasi eksplisit dalam kode Anda.

    Anda dapat mengatur standar berbeda untuk kelas atau metode jika NNEL tidak bekerja untuk Anda.

  3. Kerangka kerja ini memungkinkan Anda untuk menggunakan tanpa membuat ketergantungan pada kerangka kerja dengan melampirkan penjelasan Anda dalam komentar: misalnya /*@Nullable*/. Ini bagus karena Anda dapat membuat anotasi dan memeriksa pustaka atau kode bersama, tetapi masih dapat menggunakan pustaka / kode bersama dalam proyek lain yang tidak menggunakan kerangka kerja. Ini adalah fitur yang bagus. Saya sudah terbiasa menggunakannya, meskipun saya cenderung mengaktifkan Kerangka Pemeriksa pada semua proyek saya sekarang.

  4. Kerangka kerja ini memiliki cara untuk membubuhi keterangan API yang Anda gunakan yang belum dijelaskan untuk nullness dengan menggunakan file rintisan.


3
Tampak hebat dan saya ingin menggunakannya, tetapi tidak bisa. Mengapa GPL? Bukankah itu LGPL saja?
Burkhard

13
Menurut FAQ : "Lisensi MIT yang lebih permisif berlaku untuk kode yang mungkin ingin Anda sertakan dalam program Anda sendiri, seperti anotasi."
seanf

1
Tautan saat ini rusak. Tapi +1 untuk saran tentang cara menggunakan Checker Framework.
Paul Wagland

1
Sangat disayangkan bahwa checker ketidakmampuan dijatuhkan dalam rilis terbaru.
Franklin Yu

1
Kerangka Pemeriksa juga disarankan dalam Tutorial Oracle Java .
Quazi Irfan

55

Saya menggunakan IntelliJ, karena saya sebagian besar khawatir dengan IntelliJ menandai hal-hal yang mungkin menghasilkan NPE. Saya setuju bahwa frustasi karena tidak memiliki anotasi standar di JDK. Ada pembicaraan untuk menambahkannya, mungkin membuatnya menjadi Java 7. Dalam hal ini akan ada satu lagi untuk dipilih!


68
Pembaruan: IntelliJ sekarang mendukung semua anotasi di atas untuk menyoroti kode, jadi Anda tidak lagi terbatas pada anotasi IntelliJ: blogs.jetbrains.com/idea/2011/03/…
Daniel Alexiuc

31
Dan Eclipse Juno juga begitu!
jFrenetic

5
javax.annotation.Nonnulllebih diterima secara luas, bukan?
Martin

1
@DanielAlexiuc Tapi sayangnya, itu tidak menggunakannya untuk pemeriksaan runtime, jadi masih ada manfaat menggunakan JetBrains ...
Trejkaz

4
@Trejkaz Sejak 2016.3 ia menciptakan pemeriksaan runtime untuk semua itu.
Karol S

32

Menurut daftar fitur Java 7 JSR-308 anotasi jenis ditangguhkan ke Java 8. Anotasi JSR-305 bahkan tidak disebutkan.

Ada sedikit info tentang status JSR-305 dalam lampiran draft JSR-308 terbaru. Ini termasuk pengamatan bahwa anotasi JSR-305 tampaknya ditinggalkan. Halaman JSR-305 juga menunjukkannya sebagai "tidak aktif".

Sementara itu, jawaban pragmatis adalah menggunakan jenis anotasi yang didukung oleh alat yang paling banyak digunakan ... dan bersiaplah untuk mengubahnya jika situasinya berubah.


Bahkan, JSR-308 tidak mendefinisikan jenis / kelas penjelasan, dan sepertinya mereka pikir itu di luar jangkauan. (Dan mereka benar, mengingat keberadaan JSR-305).

Namun, jika JSR-308 benar-benar terlihat seperti berhasil masuk ke Java 8, tidak akan mengejutkan saya jika minat pada JSR-305 dihidupkan kembali. AFAIK, tim JSR-305 belum secara resmi meninggalkan pekerjaan mereka. Mereka baru saja diam selama 2+ tahun.

Sangat menarik bahwa Bill Pugh (pemimpin teknologi untuk JSR-305) adalah salah satu orang di belakang FindBugs.


4
@pst - jadwal saat ini adalah untuk Java 8 untuk rilis umum pada bulan September 2013 - infoq.com/news/2012/04/jdk-8-milestone-release-dates
Stephen C

2
Itu telah merosot ke Maret 2014 sekarang - openjdk.java.net/projects/jdk8 . JSR 308 termasuk dalam build M7 (lihat "104 - Annotations on Java Types").
Stephen C

28

Untuk proyek Android Anda harus menggunakan android.support.annotation.NonNulldan android.support.annotation.Nullable. Ini dan anotasi khusus Android yang bermanfaat lainnya tersedia di Perpustakaan Dukungan .

Dari http://tools.android.com/tech-docs/support-annotations :

Pustaka dukungan itu sendiri juga telah dijelaskan dengan anotasi ini, sehingga sebagai pengguna pustaka dukungan, Android Studio sudah akan memeriksa kode Anda dan menandai kemungkinan masalah berdasarkan anotasi ini.


3
Akan bermanfaat untuk memberikan pembenaran untuk rekomendasi itu.
aprikot

2
tools.android.com/tech-docs/support-annotations "Pustaka dukungan itu sendiri juga telah dijelaskan dengan anotasi ini, sehingga sebagai pengguna pustaka dukungan, Android Studio sudah akan memeriksa kode Anda dan menandai kemungkinan masalah berdasarkan anotasi ini. . "
James Wald

3
BTW Android Studio mendukung jsr305 dengan javax.annotation.*anotasi juga
CAMOBAP

19

Jika ada yang hanya mencari kelas IntelliJ: Anda bisa mendapatkannya dari repositori maven

<dependency>
    <groupId>org.jetbrains</groupId>
    <artifactId>annotations</artifactId>
    <version>15.0</version>
</dependency> 

Ini yang menyebabkan Intellij memuntahkan peringatan, ya.
Klik Upvote

Versi saat ini (per 05/2017) adalah 15.0
BamaPookie

Kanan Anda. Saya telah memperbarui versinya. Bahkan jika saya kira itu tidak banyak berubah.
Bruno Eberhard

Perlu diingat bahwa anotasi JetBrains tidak disimpan untuk runtime, jadi dukungan Guice @Nullable misalnya tidak berfungsi dengannya.
Peter Major

18

JSR305 dan FindBugs ditulis oleh orang yang sama. Keduanya dipelihara dengan buruk tetapi standar seperti yang didapat dan didukung oleh semua IDE utama. Berita baiknya adalah mereka bekerja dengan baik apa adanya.

Inilah cara menerapkan @Nonnull ke semua kelas, metode, dan bidang secara default. Lihat https://stackoverflow.com/a/13319541/14731 dan https://stackoverflow.com/a/9256595/14731

  1. Menetapkan @NotNullByDefault
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;


    /**
     * This annotation can be applied to a package, class or method to indicate that the class fields,
     * method return types and parameters in that element are not null by default unless there is: <ul>
     * <li>An explicit nullness annotation <li>The method overrides a method in a superclass (in which
     * case the annotation of the corresponding parameter in the superclass applies) <li> there is a
     * default parameter annotation applied to a more tightly nested element. </ul>
     * <p/>
     * @see https://stackoverflow.com/a/9256595/14731
     */
    @Documented
    @Nonnull
    @TypeQualifierDefault(
    {
        ElementType.ANNOTATION_TYPE,
        ElementType.CONSTRUCTOR,
        ElementType.FIELD,
        ElementType.LOCAL_VARIABLE,
        ElementType.METHOD,
        ElementType.PACKAGE,
        ElementType.PARAMETER,
        ElementType.TYPE
    })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface NotNullByDefault
    {
    }

2. Tambahkan anotasi ke setiap paket: package-info.java

@NotNullByDefault
package com.example.foo;

UPDATE : Pada 12 Desember 2012 JSR 305 terdaftar sebagai "Tidak Aktif". Menurut dokumentasi:

JSR yang dipilih sebagai "tidak aktif" oleh Komite Eksekutif, atau yang telah mencapai akhir masa pakainya.

Sepertinya JSR 308 adalah membuatnya menjadi JDK 8 dan meskipun JSR tidak mendefinisikan @NotNull, yang menyertai Checkers Frameworktidak. Pada saat penulisan ini, plugin Maven tidak dapat digunakan karena bug ini: https://github.com/typetools/checker-framework/issues/183


2
Masalah showstopper untuk maven diperbaiki. Jadi ini harus menjadi pilihan lagi.
Marc von Renteln

Saya menggunakan FindBugs via Maven, tidak ada yang dilakukan oleh IDE saya, ini menghindari penjelasan spesifik IDE, apa yang akan Anda rekomendasikan?
Christophe Roussy

@ChristopheRoussy Pertanyaan Anda khusus untuk IDE. Silakan buka pertanyaan terpisah.
Gili

15

Bedakan antara analisis statis dan analisis runtime. Gunakan analisis statis untuk hal-hal internal, dan analisis runtime untuk batas publik kode Anda.

Untuk hal-hal yang tidak boleh nol:

  • Pemeriksaan runtime: Gunakan "jika (x == null) ..." (nol ketergantungan) atau @ javax.validation.NotNull (dengan validasi kacang) atau @ lombok.NonNull (polos dan sederhana) atau jambu biji Preconditions.checkNotNull (.. .)

    • Gunakan Opsional untuk jenis pengembalian metode (hanya). Entah Java8 atau Jambu Biji.
  • Pemeriksaan statis: Gunakan anotasi @NonNull

  • Jika cocok, gunakan @ ... NonnullByDefault anotasi pada tingkat kelas atau paket. Buat sendiri anotasi ini (contoh mudah ditemukan).
    • Lain, gunakan @ ... CheckForNull pada metode pengembalian untuk menghindari NPE

Ini harus memberikan hasil terbaik: peringatan di IDE, kesalahan oleh Findbugs dan checkerframework, pengecualian runtime yang berarti.

Jangan berharap pemeriksaan statis menjadi matang, penamaannya tidak standar dan pustaka dan IDE yang berbeda memperlakukannya secara berbeda, abaikan saja. Kelas JSR305 javax.annotations. * Terlihat seperti standar, tetapi tidak, dan menyebabkan paket terpisah dengan Java9 +.

Beberapa penjelasan penjelasan:

  • Anotasi Findbugs / spotbugs / jsr305 dengan package javax.validation. * Bentrok dengan modul lain di Java9 +, juga mungkin melanggar lisensi Oracle
  • Anotasi Spotbugs masih tergantung pada jsr305 / anotasi findbugs pada saat bersamaan (pada saat penulisan https://github.com/spotbugs/spotbugs/issues/421 )
  • jetbrains @NotNull bertentangan dengan @ javax.validation.NotNull.
  • jetbrains, gerhana, atau anotasi pengerjaan checker untuk pengecekan statis memiliki keunggulan dibandingkan javax. Peringatan bahwa mereka tidak berbenturan dengan modul lain di Java9 dan lebih tinggi
  • @ javax.annotations.Nullable tidak berarti mencari Findbugs / Spotbugs seperti yang Anda (atau IDE) pikirkan. Findbugs akan mengabaikannya (pada anggota). Sedih, tetapi benar ( https://sourceforge.net/p/findbugs/bugs/1181 )
  • Untuk pemeriksaan statis di luar IDE, ada 2 alat gratis: Spotbugs (sebelumnya Findbugs) dan checkersframework.
  • Pustaka Eclipse memiliki @NonNullByDefault, jsr305 hanya memiliki @ParametersAreNonnullByDefault. Itu hanyalah pembungkus praktis yang menerapkan anotasi dasar untuk semua yang ada dalam suatu paket (atau kelas), Anda dapat dengan mudah membuatnya sendiri. Ini dapat digunakan pada paket. Ini mungkin bertentangan dengan kode yang dihasilkan (misalnya lombok).
  • Menggunakan lombok sebagai dependensi yang diekspor harus dihindari untuk perpustakaan yang Anda bagikan dengan orang lain, semakin sedikit ketergantungan transitif, semakin baik
  • Menggunakan kerangka validasi Bean sangat kuat, tetapi membutuhkan overhead yang tinggi, jadi itu berlebihan hanya untuk menghindari pemeriksaan null manual.
  • Menggunakan Opsional untuk bidang dan parameter metode kontroversial (Anda dapat menemukan artikel tentang itu dengan mudah)
  • Android null annotations adalah bagian dari perpustakaan dukungan Android, mereka hadir dengan banyak kelas lain, dan tidak bermain dengan baik dengan anotasi / alat lainnya

Sebelum Java9, ini adalah rekomendasi saya:

// file: package-info.java
@javax.annotation.ParametersAreNonnullByDefault
package example;


// file: PublicApi
package example;

public interface PublicApi {

    Person createPerson(
        // NonNull by default due to package-info.java above
        String firstname,
        String lastname);
}

// file: PublicApiImpl
public class PublicApiImpl implements PublicApi {
    public Person createPerson(
            // In Impl, handle cases where library users still pass null
            @Nullable String firstname, // Users  might send null
            @Nullable String lastname // Users might send null
            ) {
        if (firstname == null) throw new IllagalArgumentException(...);
        if (lastname == null) throw new IllagalArgumentException(...);
        return doCreatePerson(fistname, lastname, nickname);
    }

    @NonNull // Spotbugs checks that method cannot return null
    private Person doCreatePerson(
             String firstname, // Spotbugs checks null cannot be passed, because package has ParametersAreNonnullByDefault
             String lastname,
             @Nullable String nickname // tell Spotbugs null is ok
             ) {
         return new Person(firstname, lastname, nickname);
    }

    @CheckForNull // Do not use @Nullable here, Spotbugs will ignore it, though IDEs respect it
    private Person getNickname(
         String firstname,
         String lastname) {
         return NICKNAMES.get(firstname + ':' + lastname);
    }
}

Perhatikan bahwa tidak ada cara untuk membuat Spotbugs membangkitkan peringatan ketika parameter metode nullable dereferenced (pada saat penulisan, versi 3.1 dari Spotbugs). Mungkin checkerframework bisa melakukannya.

Sayangnya, anotasi ini tidak membedakan antara kasus-kasus metode umum perpustakaan dengan panggilan sewenang-wenang, dan metode non-publik di mana setiap lokasi panggilan dapat diketahui. Jadi makna ganda dari: "Tunjukkan bahwa null tidak diinginkan, tetapi persiapkan untuk null yang disahkan" tidak mungkin dalam satu deklarasi, oleh karena itu contoh di atas memiliki anotasi yang berbeda untuk antarmuka dan implementasi.

Untuk kasus-kasus di mana pendekatan pemisahan antarmuka tidak praktis, pendekatan berikut adalah kompromi:

        public Person createPerson(
                @NonNull String firstname,
                @NonNull String lastname
                ) {
            // even though parameters annotated as NonNull, library clients might call with null.
            if (firstname == null) throw new IllagalArgumentException(...);
            if (lastname == null) throw new IllagalArgumentException(...);
            return doCreatePerson(fistname, lastname, nickname);
        }

Ini membantu klien untuk tidak lulus nol (menulis kode yang benar), sambil mengembalikan kesalahan yang bermanfaat jika mereka melakukannya.


Saya menemukan jawaban ini hanya sekarang, tetapi @tkruse, di mana Anda menemukan ini: "Anotasi Eclipse jdt tidak berlaku untuk pengembalian metode statis dan beberapa kasus lainnya"? (bagian pertama tidak benar, yang kedua cukup samar :)).
Stephan Herrmann

@StephanHerrmann: Saya tidak ingat. Saya menghapus titik peluru.
tkruse

12

Eclipse juga memiliki anotasi sendiri.

org.eclipse.jdt.annotation.NonNull

Lihat di http://wiki.eclipse.org/JDT_Core/Null_Analysis untuk detailnya.


Sepertinya ini akan diintegrasikan dari Eclipse 3.8 (Juno) yang akan membawa Eclipse sejalan dengan IntelliJ dalam hal ini. Juga harus memungkinkan Anda untuk mengkonfigurasi anotasi Null Anda sendiri (mis. Javax.annotation.Nonnull) dan memiliki opsi untuk menjadikan NotNull sebagai default.
Motti Strom

11

Hanya menunjukkan bahwa Java Validation API ( javax.validation.constraints.*) tidak datang dengan @Nullableanotasi, yang sangat berharga dalam konteks analisis statis. Masuk akal untuk validasi kacang runtime karena ini adalah default untuk setiap bidang non-primitif di Jawa (yaitu tidak ada yang memvalidasi / menegakkan). Untuk tujuan yang dinyatakan harus mempertimbangkan alternatif.


7

Sayangnya, JSR 308tidak akan menambahkan nilai lebih dari proyek ini. Tidak ada saran Null di sini

Java 8tidak akan datang dengan anotasi standar tunggal atau Checkerkerangka kerjanya sendiri . Mirip dengan Find-bug atau JSR 305, JSR ini tidak dikelola dengan baik oleh sekelompok kecil tim akademis.

Tidak ada kekuatan komersial di baliknya, sehingga JSR 308meluncurkan EDR 3(Early Draft Review at JCP) SEKARANG, sementara Java 8seharusnya dikirimkan dalam waktu kurang dari 6 bulan: -O Mirip dengan 310btw. tetapi tidak seperti yang 308 Oracletelah mengambil alih itu sekarang jauh dari pendirinya untuk meminimalkan bahaya itu akan dilakukan ke Platform Java.

Setiap proyek, vendor dan kelas akademik seperti yang ada di belakang Checker Frameworkdan JSR 308akan membuat anotasi pemeriksa hak miliknya sendiri.

Membuat kode sumber yang tidak kompatibel tahun-tahun mendatang, sampai beberapa kompromi populer dapat ditemukan dan mungkin ditambahkan ke Java 9atau 10, atau melalui kerangka kerja seperti Apache Commonsatau Google Guava;-)


7

Android

Jawaban ini khusus untuk Android. Android memiliki paket dukungan yang disebut support-annotations. Ini menyediakan puluhan dari spesifik Android penjelasan dan juga menyediakan yang umum seperti NonNull, Nullabledll

Untuk menambahkan paket anotasi dukungan , tambahkan dependensi berikut di build.gradle Anda:

compile 'com.android.support:support-annotations:23.1.1'

lalu gunakan:

import android.support.annotation.NonNull;

void foobar(@NonNull Foo bar) {}

5

Sambil menunggu ini diselesaikan di hulu (Java 8?), Anda juga bisa mendefinisikan proyek-lokal @NotNulldan @Nullableanotasi Anda sendiri . Ini dapat berguna juga jika Anda bekerja dengan Java SE, di mana javax.validation.constraints tidak tersedia secara default.

import java.lang.annotation.*;

/**
 * Designates that a field, return value, argument, or variable is
 * guaranteed to be non-null.
 */
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})
@Documented
@Retention(RetentionPolicy.CLASS)
public @interface NotNull {}

/**
 * Designates that a field, return value, argument, or variable may be null.
 */
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})
@Documented
@Retention(RetentionPolicy.CLASS)
public @interface Nullable {}

Ini diakui sebagian besar untuk tujuan dekoratif atau pembuktian di masa depan, karena di atas jelas tidak dengan sendirinya menambah dukungan untuk analisis statis anotasi ini.


4

Jika Anda mengembangkan untuk android, Anda agak terikat dengan Eclipse (edit: pada saat penulisan, tidak lagi), yang memiliki anotasi sendiri. Ini termasuk dalam Eclipse 3.8+ (Juno), tetapi dinonaktifkan secara default.

Anda dapat mengaktifkannya di Preferensi> Java> Kompiler> Kesalahan / Peringatan> Analisis kosong (bagian yang dapat diciutkan di bagian bawah).

Centang "Aktifkan analisis nol berbasis anotasi"

http://wiki.eclipse.org/JDT_Core/Null_Analysis#Usage memiliki rekomendasi tentang pengaturan. Namun, jika Anda memiliki proyek eksternal di ruang kerja Anda (seperti SDK facebook), mereka mungkin tidak memenuhi rekomendasi tersebut, dan Anda mungkin tidak ingin memperbaikinya dengan setiap pembaruan SDK ;-)

Saya menggunakan:

  1. Akses penunjuk kosong: Kesalahan
  2. Pelanggaran spesifikasi nol: Kesalahan (terkait dengan poin # 1)
  3. Potensi akses penunjuk nol: Peringatan (jika tidak, SDK facebook akan memiliki peringatan)
  4. Konflik antara anotasi nol dan inferensi nol: Peringatan (ditautkan ke titik # 3)

4
terkait dengan Eclipse? Tidak benar.
dcow

1
@DavidCowden IntelliJ IDEA dengan dukungan untuk Android dev`ing, saya pikir, sudah tersedia beberapa saat sebelum AndroidStudio terlibat.
Mārtiņš Briedis

@ MārtiņšBriedis ya, itu benar. Saya pikir Anda maksud @chaqke.
dcow

Perlu dicatat bahwa Android dan Intellij memiliki anotasi yang terpisah, dan kemungkinan akan tetap seperti itu sampai java menyertakan anotasi resmi. ini adalah petunjuk untuk menggunakan anotasi eclipse dengan eclipse.
chaqke

Itu belum pernah dikaitkan dengan Eclipse. Anda dapat menggunakan IDE apa pun yang Anda inginkan.
DennisK

4

Jika Anda mengerjakan proyek besar, Anda mungkin lebih baik membuat sendiri @Nullable dan / atau @NotNullanotasi.

Sebagai contoh:

@java.lang.annotation.Documented
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)
@java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD,
                              java.lang.annotation.ElementType.METHOD,    
                              java.lang.annotation.ElementType.PARAMETER,
                              java.lang.annotation.ElementType.LOCAL_VARIABLE})
public @interface Nullable 
{
}

Jika Anda menggunakan kebijakan penyimpanan yang benar , maka anotasi tidak akan tersedia saat runtime . Dari sudut pandang itu, itu hanya hal internal .

Meskipun ini bukan ilmu yang ketat, saya pikir paling masuk akal untuk menggunakan kelas internal untuk itu.

  • Ini adalah hal internal. (tidak ada dampak fungsional atau teknis)
  • Dengan banyak banyak penggunaan.
  • IDE seperti IntelliJ mendukung kustom @Nullable/ @NotNullanotasi.
  • Sebagian besar kerangka kerja lebih suka menggunakan versi internal mereka sendiri.

Pertanyaan Tambahan (lihat komentar):

Bagaimana cara mengkonfigurasi ini di IntelliJ?

Klik "petugas polisi" di sudut kanan bawah bilah status IntelliJ. Dan klik "Konfigurasikan inspeksi" di sembulan. Lanjut ... konfigurasikan anotasi


1
Saya mencoba saran Anda, tetapi ideajangan katakan tentang void test(@NonNull String s) {}dipanggil olehtest(null);
user1244932

3
@ user1244932 Apakah maksud Anda IntelliJ IDEA? Anda dapat mengkonfigurasi anotasi nullability yang digunakannya untuk analisis statis. Saya tidak tahu persis di mana, tetapi satu tempat untuk mendefinisikannya adalah di "File> Settings> Build, Execution, Deployment> Compiler" dan ada tombol "Configure annotations ...".
Adowrath

@ user1244932 lihat tangkapan layar jika Anda masih mencari ini.
bvdb

3

Sudah ada terlalu banyak jawaban di sini, tetapi (a) ini tahun 2019, dan masih belum ada "standar" Nullabledan (b) tidak ada jawaban lain yang merujuk Kotlin.

Referensi ke Kotlin penting, karena Kotlin 100% dapat dioperasikan dengan Java dan memiliki fitur inti Null Safety. Saat memanggil pustaka Java, itu bisa memanfaatkan anotasi tersebut untuk memberi tahu Kotlin alat apakah API Java dapat menerima atau kembali null.

Sejauh yang saya tahu, satu-satunya Nullablepaket yang kompatibel dengan Kotlin adalah org.jetbrains.annotationsdan android.support.annotation(sekarang androidx.annotation). Yang terakhir hanya kompatibel dengan Android sehingga tidak dapat digunakan dalam proyek JVM / Java / Kotlin non-Android. Namun, paket JetBrains bekerja di mana-mana.

Jadi, jika Anda mengembangkan paket Java yang juga harus berfungsi di Android dan Kotlin (dan didukung oleh Android Studio dan IntelliJ), pilihan terbaik Anda mungkin adalah paket JetBrains.

Maven:

<dependency>
    <groupId>org.jetbrains</groupId>
    <artifactId>annotations-java5</artifactId>
    <version>15.0</version>
</dependency>

Gradle:

implementation 'org.jetbrains:annotations-java5:15.0'

2
Hmm, ini mengatakan sebaliknya: kotlinlang.org/docs/reference/…
skagedal

3

Ada cara lain untuk melakukan ini di Jawa 8. Saya melakukan 2 hal untuk mencapai apa yang saya butuhkan:

  1. Membuat bidang nullable eksplisit dengan jenis dengan membungkus bidang nullable dengan java.util.Optional
  2. Memeriksa bahwa semua bidang yang tidak dapat dibatalkan tidak nol pada saat konstruksi dengan java.util.Objects.requireNonNull

Contoh:

import static java.util.Objects.requireNonNull;

public class Role {

  private final UUID guid;
  private final String domain;
  private final String name;
  private final Optional<String> description;

  public Role(UUID guid, String domain, String name, Optional<String> description) {
    this.guid = requireNonNull(guid);
    this.domain = requireNonNull(domain);
    this.name = requireNonNull(name);
    this.description = requireNonNull(description);
  }

Jadi pertanyaan saya adalah, apakah kita perlu membuat catatan ketika menggunakan java 8?

Sunting: Saya menemukan kemudian bahwa beberapa menganggap praktik buruk untuk digunakan Optionaldalam argumen, ada diskusi yang baik dengan pro dan kontra di sini Mengapa Java 8's Opsional tidak boleh digunakan dalam argumen

Opsi alternatif mengingat bahwa tidak disarankan untuk menggunakan Opsional dalam argumen, kita membutuhkan 2 konstruktor:

  //Non null description
  public Role(UUID guid, String domain, String name, String description) {
        this.guid = requireNonNull(guid);
        this.domain = requireNonNull(domain);
        this.name = requireNonNull(name);

        // description will never be null
        requireNonNull(description);

        // but wrapped with an Optional
        this.description = Optional.of(description);
      }

  // Null description is assigned to Optional.empty
  public Role(UUID guid, String domain, String name) {
        this.guid = requireNonNull(guid);
        this.domain = requireNonNull(domain);
        this.name = requireNonNull(name);
        this.description = Optional.empty();
      }

Saya akan mengatakan Anda masih membutuhkan penjelasan @NotNull untuk semua 4 parameter formal sehingga pemeriksa analisis statis tahu niat Anda bahwa tidak ada yang harus nol. Tidak ada dalam bahasa Jawa yang memberlakukan itu. Anda juga harus memeriksa bahwa deskripsi tersebut tidak nol jika Anda memprogram dengan defensif.
jaxzin

2
Saya masih bisa menulis kode ini: new Role(null,null,null,null);. Dengan anotasi, IDE dan analisis statis saya akan memperingatkan bahwa nol tidak dapat diteruskan ke parameter tersebut. Tanpa itu saya tidak tahu sampai saya menjalankan kode. Itulah nilai dari anotasi.
jaxzin

2
Saya juga dalam lingkungan di mana pengembang dapat menggunakan IDE atau editor teks apa pun yang mereka sukai, tidak saling eksklusif. Kami kemudian juga mengintegrasikan maven-pmd-plugin dan / atau SonarQube ke dalam proses build untuk mendorong dan menyoroti, dan bahkan gate, masalah kualitas kode pra-penggabungan, misalnya pada permintaan pull.
jaxzin

2
Opsional tidak dimaksudkan untuk digunakan sebagai argumen metode atau bidang pribadi. Lihat misalnya: stuartmarks.wordpress.com/2016/09/27/vjug24-session-on-optional
assylias

1
@assylias ya, saya menemukan itu nanti, mereka mengatakan itu tidak direkomendasikan karena tidak akan membelikan kita apa pun, saya pasti dapat memahami rasional mereka. Dalam hal ini saya taruh di sini, orang dapat membuat argumen description tidak nol dan kode klien dapat melewati String kosong, tetapi dalam banyak kasus mungkin berguna untuk membedakan antara String kosong dan dan tidak memiliki nilai. Terima kasih atas komentar Anda. Saya akan memperbarui jawabannya.
Mozart Brocchini

2

Tidakkah matahari punya matahari sendiri sekarang? Apa ini:
http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-com.sun/istack/com.sun.istack.internal.htm

Ini sepertinya dikemas dengan semua versi Jawa yang saya gunakan dalam beberapa tahun terakhir.

Sunting: Seperti disebutkan dalam komentar di bawah, Anda mungkin tidak ingin menggunakannya. Dalam hal itu, suara saya adalah untuk anotasi jetbrains IntelliJ!


10
Saya tidak tahu apa itu, tetapi nama paket harus merupakan petunjuk besar yang TIDAK dimaksudkan untuk penggunaan umum.
Stephen C

3
Orang biasanya menahan diri dari menggunakan kelas di com.sun namespace karena mereka internal; tidak dimaksudkan untuk penggunaan langsung; dan tanpa jaminan untuk ketersediaan atau perilaku mereka di masa depan. Kita harus memiliki kasus yang sangat kuat untuk langsung menggunakan artefak com.sun.
luis.espinal

ditambah sesuatu yang ditampilkan dalam format HTML yang buruk (di Java2s.com to top it off) akan memberi Anda beberapa bendera merah :)
luis.espinal

2

Salah satu hal baik tentang IntelliJ adalah Anda tidak perlu menggunakan anotasi mereka. Anda dapat menulis sendiri, atau menggunakan alat apa pun yang Anda suka. Anda bahkan tidak terbatas pada satu tipe pun. Jika Anda menggunakan dua pustaka yang menggunakan anotasi @NotNull yang berbeda, Anda bisa memberi tahu IntelliJ untuk menggunakan keduanya. Untuk melakukan ini, buka "Konfigurasikan Inspeksi", klik pada inspeksi "Kondisi & Pengecualian Konstan", dan tekan tombol "Konfigurasikan inspeksi". Saya menggunakan Nullness Checker di mana pun saya bisa, jadi saya mengatur IntelliJ untuk menggunakan anotasi tersebut, tetapi Anda dapat membuatnya bekerja dengan alat apa pun yang Anda inginkan. (Saya tidak memiliki pendapat tentang alat-alat lain karena saya telah menggunakan inspeksi IntelliJ selama bertahun-tahun, dan saya menyukainya.)


1

Pilihan lain adalah anotasi yang disediakan dengan ANTLR 4. Mengikuti Permintaan Tarik # 434 , artefak yang berisi @NotNulldan @Nullableanotasi mencakup prosesor anotasi yang menghasilkan kesalahan waktu kompilasi dan / atau peringatan jika salah satu atribut ini disalahgunakan (misalnya, jika keduanya diterapkan pada item yang sama, atau jika @Nullablediterapkan pada item dengan tipe primitif). Prosesor anotasi memberikan jaminan tambahan selama proses pengembangan perangkat lunak bahwa informasi yang disampaikan oleh aplikasi anotasi ini akurat, termasuk dalam kasus pewarisan metode.


1

Jika Anda sedang membangun aplikasi Anda menggunakan Spring Framework saya sarankan menggunakan javax.validation.constraints.NotNullcoming dari Beans Validation yang dikemas dalam dependensi berikut:

    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.1.0.Final</version>
    </dependency>

Keuntungan utama anotasi ini adalah Spring memberikan dukungan untuk parameter metode dan bidang kelas yang dianotasi javax.validation.constraints.NotNull. Yang perlu Anda lakukan untuk mengaktifkan dukungan adalah:

  1. memasok api jar untuk validasi kacang dan jar dengan implementasi validator jsr-303 / jsr-349 anotasi (yang dilengkapi dengan Hibernate Validator 5.x dependensi):

    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.1.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>5.4.1.Final</version>
    </dependency>
  2. memberikan MethodValidationPostProcessor ke konteks pegas

      @Configuration
      @ValidationConfig
      public class ValidationConfig implements MyService {
    
            @Bean
            public MethodValidationPostProcessor providePostProcessor() {
                  return new MethodValidationPostProcessor()
            }
      }
  3. akhirnya Anda membubuhi keterangan kelas Anda dengan Spring org.springframework.validation.annotation.Validateddan validasi akan secara otomatis ditangani oleh Spring.

Contoh:

@Service
@Validated
public class MyServiceImpl implements MyService {

  @Override
  public Something doSomething(@NotNull String myParameter) {
        // No need to do something like assert myParameter != null  
  }
}

Ketika Anda mencoba memanggil metode doSomething dan lulus nol sebagai nilai parameter, pegas (dengan menggunakan HibernateValidator) akan melempar ConstraintViolationException. Tidak perlu bekerja secara manual di sini.

Anda juga dapat memvalidasi nilai kembali.

Manfaat penting lainnya dari javax.validation.constraints.NotNullComing for Beans Validation Framework adalah bahwa saat ini masih dikembangkan dan fitur baru direncanakan untuk versi 2.0 yang baru.

Bagaimana dengan @Nullable? Tidak ada yang seperti itu di Beans Validation 1.1. Yah, saya bisa berpendapat bahwa jika Anda memutuskan untuk menggunakan @NotNulldaripada segala sesuatu yang TIDAK dijelaskan dengan @NonNullefektif "nullable", maka @Nullablepenjelasannya tidak berguna.


1
Tolong jangan gunakan itu. Ini digunakan untuk validasi runtime, BUKAN analisis kode statis. Lihat justsomejavaguy.blogspot.com/2011/08/... untuk detailnya. Sumber: jawaban DELETED dengan 219 suara oleh @ luis.espinal.
koppor

@koppor: Saya tidak setuju. Jika ini tidak dimaksudkan untuk penggunaan mengapa Spring akan menanganinya saat runtime. Kerangka validasi Beans juga memungkinkan untuk membuat anotasi murni untuk analisis runtime, karena memungkinkan untuk mengakses objek Konteks (saat ini dianotasi / divalidasi instancje) pada saat runtime.
walkeros

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.