java - ناطق - معنى كلمة عربي بالانجليزي




ما هو تعليقNotNull Java الذي يجب استخدامه؟ (13)

أنا أتطلع إلى جعل الشفرة أكثر قابلية للقراءة وكذلك استخدام الأدوات مثل فحص رمز IDE و / أو تحليل الكود الثابت (FindBugs و Sonar) لتجنب NullPointerExceptions. يبدو أن العديد من الأدوات غير متوافقة مع كل من @NotNull / @NonNull / @Nonnull وإدراجها كلها في الشفرة ستكون رهيبة للقراءة. أي اقتراحات من أي واحد هو "أفضل"؟ إليك قائمة التعليقات التوضيحية المكافئة التي وجدتها:

  • javax.validation.constraints.NotNull
    تم إنشاؤها للتحقق من وقت التشغيل ، وليس التحليل الثابت.
    documentation

  • edu.umd.cs.findbugs.annotations.NonNull
    المستخدمة من قبل تحليل ثابت Findbugs وبالتالي سونار (الآن Sonarqube )
    documentation

  • javax.annotation.Nonnull
    قد يعمل ذلك مع Findbugs أيضًا ، ولكن JSR-305 غير نشط. (راجع أيضًا: ما حالة source JSR 305؟ )

  • org.jetbrains.annotations.NotNull
    المستخدمة من قبل IntelliJ IDEA IDE لتحليل ثابت.
    documentation

  • lombok.NonNull
    تستخدم للتحكم في إنشاء الكود في مشروع لومبوك .
    تعليق العنصر النائب نظرًا لعدم وجود أي معيار.
    source documentation

  • android.support.annotation.NonNull
    يتوفر التعليق التوضيحي في Android ، ويتم توفيره من خلال حزمة التعليقات التوضيحية للدعم
    documentation

  • org.eclipse.jdt.annotation.NonNull
    تستخدم من قبل Eclipse لتحليل كود ثابت
    documentation


ذكري المظهر

هذه الإجابة محددة من Android. يتضمن Android حزمة support-annotations تسمى support-annotations . يوفر ذلك dozens من التعليقات التوضيحية http://tools.android.com/tech-docs/support-annotations ، كما يوفر dozens من التعليقات الشائعة مثل NonNull و NonNull وما إلى ذلك.

لإضافة حزمة دعم توضيحية ، أضف التبعية التالية في build.raddle الخاص بك:

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

ثم استخدم:

import android.support.annotation.NonNull;

void foobar(@NonNull Foo bar) {}

أثناء الانتظار حتى يتم فرز هذا المنبع (Java 8؟) ، يمكنك أيضًا تحديد مشروعك المحلي @NotNull و @Nullable . قد يكون هذا مفيدًا أيضًا في حالة العمل مع Java SE ، حيث لا تتوفر javax.validation.constraints افتراضيًا.

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 {}

هذا من شأنه أن يكون إلى حد كبير لأغراض التزييف أو التدقيق في المستقبل ، لأن ما ورد أعلاه لا يضيف في حد ذاته أي دعم للتحليل الساكن لهذه التعليقات.


إذا كان أي شخص يبحث عن دروس IntelliJ: يمكنك الحصول عليها من مستودع maven

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

إذا كنت تعمل في مشروع كبير ، فقد يكون من الأفضل إنشاء تعليقاتك الخاصة @Nullable و / أو @NotNull .

فمثلا:

@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 
{
}

إذا كنت تستخدم سياسة الاحتفاظ الصحيحة ، فلن تكون التعليقات التوضيحية متاحة في وقت التشغيل . من وجهة النظر هذه ، إنه مجرد أمر داخلي .

على الرغم من أن هذا ليس علمًا صارمًا ، أعتقد أنه من المنطقي استخدام صف دراسي داخلي له.

  • إنه شيء داخلي. (لا يوجد أي تأثير وظيفي أو تقني)
  • مع العديد من العديد من الاستخدامات.
  • IDE مثل دعم @NotNull التعليقات التوضيحية @NotNull / @Nullable المخصصة.
  • معظم الأطر تفضل استخدام النسخة الداخلية الخاصة بها كذلك.

أسئلة إضافية (راجع التعليقات):

كيفية تكوين هذا في IntelliJ؟

انقر فوق "ضابط الشرطة" في الزاوية اليمنى السفلى من شريط الحالة IntelliJ. وانقر على "تهيئة عمليات التفتيش" في النافذة المنبثقة. التالى ...


إنني أشبه إلى حد كبير ببرنامج Checker Framework ، وهو تنفيذ للتعليقات التوضيحية من النوع ( JSR-308 ) والذي يستخدم لتنفيذ برامج التشويش الخاطئة مثل مدقق الإلغاء. لم أحاول فعلًا تقديم أي مقارنة مع الآخرين ، ولكني كنت سعيدًا بهذا التنفيذ.

أنا لست تابعًا للمجموعة التي تقدم البرنامج ، لكنني معجب.

أربعة أشياء أحبها في هذا النظام:

  1. يحتوي على مجموعة من العيوب nullness (Nullable) ، ولكنه يحتوي أيضًا على العيوب من أجل nullness والتدرب (وغيرها). أنا استخدم أول واحد (البطلان) وأنا أحاول الدخول في استخدام الثاني (immutability / IGJ). أحاول الخروج من البرنامج الثالث ، لكنني لست متأكدة من استخدامه على المدى الطويل حتى الآن. لست مقتنعاً بالفائدة العامة التي يتمتع بها المدققون الآخرون بعد ، ولكن من الجميل أن نعرف أن الإطار نفسه هو نظام لتنفيذ مجموعة متنوعة من التعليقات الإضافية والدقائق.

  2. الإعداد الافتراضي للتحقق من البطل يعمل بشكل جيد: Non-null باستثناء local (NNEL). يعني هذا بشكل أساسي أن المدقق يعامل بشكل افتراضي كل شيء (متغيرات الحالة ، معلمات الأسلوب ، أنواع عامة ، إلخ) باستثناء المتغيرات المحلية كما لو كان لديهمNonNull من النوع بشكل افتراضي. حسب الوثائق:

    يؤدي الإعداد الافتراضي NNEL إلى أصغر عدد من التعليقات التوضيحية الواضحة في التعليمة البرمجية.

    يمكنك تعيين إعداد افتراضي مختلف لفئة أو لأية طريقة إذا لم يعمل NNEL من أجلك.

  3. يسمح لك هذا الإطار باستخدامه بدون إنشاء تبعية للإطار من خلال تضمين التعليقات التوضيحية في تعليق: على سبيل المثال /*@Nullable*/ . وهذا أمر جيد لأنه يمكنك وضع تعليق توضيحي على مكتبة أو شفرة مشتركة والتحقق منها ، ولكن لا يزال بإمكانك استخدام تلك المكتبة / المشفرة المشتركة في مشروع آخر لا يستخدم إطار العمل. هذه هي ميزة لطيفة. لقد اعتدت على استخدامها ، على الرغم من أنني أميل إلى تمكين تطبيق Checker Framework في جميع مشروعاتي الآن.

  4. يحتوي إطار العمل على طريقة لإضافة تعليقات توضيحية لواجهة برمجة التطبيقات (APIs) التي لا تستخدمها حاليًا عن طريق استخدام ملفات كعب الروتين.


بالنسبة إلى مشروعات Android ، يجب استخدام android.support.annotation.NonNull و android.support.annotation.Nullable . تتوفر هذه التعليقات والتعليقات التوضيحية المفيدة الأخرى المخصصة لنظام التشغيل Android في مكتبة الدعم .

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

تم أيضًا إضافة تعليقات إلى مكتبة الدعم نفسها باستخدام هذه التعليقات التوضيحية ، لذا سيفحص Android Studio شفرتك ويبلغ عن المشاكل المحتملة استنادًا إلى هذه التعليقات.


لسوء الحظ ، لن يضيف JSR 308 قيمًا أكثر من هذا الاقتراح المحلي Not Null هنا

لن تأتي Java 8 مع تعليق افتراضي افتراضي أو إطار Checker خاص بها. على غرار البحث عن البق أو JSR 305 ، يتم الحفاظ على هذا JSR سيئة من قبل مجموعة صغيرة من الفرق الأكاديمية في الغالب.

لا توجد قوة تجارية وراءها ، وبالتالي فإن JSR 308 تطلق EDR 3 (مراجعة مسودة مبكرة في JCP ) الآن ، بينما من المفترض أن يتم شحن Java 8 في أقل من 6 أشهر: -O يشبه 310 btw. ولكن خلافاً لـ 308 Oracle فقد تولت 308 Oracle مسئولية ذلك الآن بعيداً عن مؤسسيها لتقليل الضرر الذي ستلحقه بجهاز Java الأساسي.

كل مشروع ، بائع وفصل أكاديمي مثل أولئك الذين يقفون وراء Checker Framework و JSR 308 الخاصة بالمدققين.

جعل شفرة المصدر غير متوافقة لسنوات قادمة ، حتى يمكن العثور على بعض التنازلات الشائعة وربما تمت إضافتها إلى Java 9 أو 10 ، أو عبر أطر عمل مثل Apache Commons أو Google Guava ؛-)


مجرد الإشارة إلى أن Java Validation API ( javax.validation.constraints.* ) لا تأتي مع تعليق توضيحي @Nullable ، وهو أمر ذو قيمة كبيرة في سياق التحليل الثابت. من المنطقي التحقق من صحة وقت تشغيل الفاصلين حيث أن هذا هو الإعداد الافتراضي لأي حقل غير بدائي في Java (أي لا شيء للتحقق / التحقق). للأغراض المذكورة يجب أن تزن نحو البدائل.


هناك طريقة أخرى للقيام بذلك في Java 8. أقوم بأمرين لإنجاز ما أحتاجه:

  1. جعل حقول nullable صريحة بأنواع بلف حقول nullable مع java.util.Optional
  2. التحقق من أن جميع الحقول غير القابلة للقيمة غير فارغة في وقت الإنشاء مع java.util.Objects.requireNonNull

مثال:

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);
  }

لذا ، سؤالي هو ، هل نحتاج حتى إلى التعليق عند استخدام جافا 8؟

تحرير: اكتشفت لاحقًا أن البعض يعتبر ممارسة سيئة لاستخدام Optional في الحجج ، هناك مناقشة جيدة مع الإيجابيات والسلبيات هنا لماذا يجب عدم استخدام Java 8's Optional في الوسيطات


وفقا لقائمة خصائص Java 7 ، يتم تأجيل التعليقات التوضيحية من النوع JSR-308 إلى Java 8. ولا يتم ذكر التعليقات التوضيحية JSR-305 حتى.

هناك بعض المعلومات عن حالة JSR-305 في appendix لأحدث مسودة JSR-308. يتضمن ذلك ملاحظة أن التعليقات التوضيحية لـ JSR-305 تبدو وكأنها تم التخلي عنها. تعرض صفحة JSR-305 أيضًا أنها "غير نشطة".

في الوقت نفسه ، تكون الإجابة البراغماتية هي استخدام أنواع التعليقات التوضيحية التي تدعمها الأدوات الأكثر استخدامًا ... وتكون مستعدًا لتغييرها إذا تغير الوضع.

في الواقع ، لا يعرّف JSR-308 أي أنواع / فئات للتعليقات ، ويبدو أنها تعتقد أنها خارج النطاق. (وهم على حق ، نظرا لوجود JSR-305).

ومع ذلك ، إذا كان JSR-308 يبدو بالفعل وكأنه جعله في Java 8 ، فلن يفاجئني إذا تم إحياء الاهتمام بـ JSR-305. AFAIK ، لم يتخل فريق JSR-305 رسمياً عن أعمالهم. لقد كانوا هادئين لمدة 2+ سنوات.

من المثير للاهتمام أن Bill Pugh (قائد فريق JSR-305) هو أحد الأشخاص الذين يبحثون عن FindBugs.



Another option is the annotations provided with ANTLR 4. Following Pull Request #434 , the artifact containing the @NotNull and @Nullable annotations includes an annotation processor that produces compile-time errors and/or warnings in the event one of these attributes is misused (for example, if both are applied to the same item, or if @Nullable is applied to item with a primitive type). The annotation processor provides additional assurance during the software development process that the information conveyed by the application of these annotations is accurate, including in cases of method inheritance.


If you are building your application using Spring Framework I would suggest using javax.validation.constraints.NotNull comming from Beans Validation packaged in following dependency:

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

The main advantage of this annotation is that Spring provides support for both method parameters and class fields annotated with javax.validation.constraints.NotNull . All you need to do to enable support is:

  1. supply the api jar for beans validation and jar with implementation of validator of jsr-303/jsr-349 annotations (which comes with Hibernate Validator 5.x dependency):

    <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. provide MethodValidationPostProcessor to spring's context

      @Configuration
      @ValidationConfig
      public class ValidationConfig implements MyService {
    
            @Bean
            public MethodValidationPostProcessor providePostProcessor() {
                  return new MethodValidationPostProcessor()
            }
      }
    
  3. finally you annotate your classes with Spring's org.springframework.validation.annotation.Validated and validation will be automatically handled by Spring.

مثال:

@Service
@Validated
public class MyServiceImpl implements MyService {

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

When you try calling method doSomething and pass null as the parameter value, spring (by means of HibernateValidator) will throw ConstraintViolationException . No need for manuall work here.

You can also validate return values.

Another important benefit of javax.validation.constraints.NotNull comming for Beans Validation Framework is that at the moment it is still developed and new features are planned for new version 2.0.

What about @Nullable ? There is nothing like that in Beans Validation 1.1. Well, I could arguee that if you decide to use @NotNull than everything which is NOT annotated with @NonNull is effectively "nullable", so the @Nullable annotation is useless.





ide