Java.util. @ Nullable ne anlama geliyor?


56

Bazı kodda ek açıklamayı bulduğum Guava kodunu okuyorum java.util.@Nullable. Anlamını biliyorum @Nullable, ama bunu anlamıyorum. Özellikle, Nullablepakette adı verilen bir sınıf bulamıyorum java.util. Lütfen biri bana bunun ne anlama geldiğini söyle java.util.@Nullable:

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

4
@PaulRooney Ben öyle düşünmüyorum. Nullableİçinde var gibi görünüyor hakkında onlar konuşuyorlar javax.annotationdeğil java.util.
Joseph Sible-Reinstate Monica

3
Bunun garip bir Java-sözdizimi-ism olup olmadığını merak ediyorum. Özellikle, bu temelde sadece anlamına gelebilir public static <T> @Nullable java.util.Optional<T> toJavaUtil, ancak Java bunu yazmanıza izin vermez mi?
Joseph Sible-Reinstate Monica

1
@JosephSible public static <T> @Nullable java.util.Optional<T> toJavaUtilgerçekten mümkün değildir, ancak Optionaliçe aktarma işlemi zaten mevcut olduğunda FQN'yi kullanmak için hiçbir neden yoktur.
Tom

6
@Tom Kapsamda başka bir şey daha Optionalvar.
Joseph Sible-Reinstate Monica

2
teşekkürler çocuklar, bu Checker Framework buldum. @Nullable java.util.List 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. But, it’s usually better to add import java.util.List to your source file, so that you can just write @Nullable List.
SetDaemon

Yanıtlar:


37

Çizgi public static <T> java.util.@Nullable Optional<T> toJavaUtilböyle yazılır, çünkü normal stil public static <T> @Nullable java.util.Optional<T> toJavaUtilgeçersiz. Bu JLS §9.7.4'te tanımlanmıştır :

T türünde bir ek açıklama, bir tür bağlamında bir türe (veya bir türün herhangi bir bölümüne) uygulanırsa ve T, tür bağlamlarında uygulanabilirse ve ek açıklamaya izin verilmezse derleme zamanı hatasıdır.

Örneğin, sadece meta açıklamalı bir açıklama türü TA olduğunu varsayalım @Target(ElementType.TYPE_USE). Terimler yasadışıdır @TA java.lang.Objectve java.@TA lang.Object@TA'nın en yakın olduğu basit ad bir paket adı olarak sınıflandırılır. Diğer yandan java.lang.@TA Objectyasaldır.

Tür bildirimi org.checkerframework.checker.nullness.qual@Nullable:

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

Yani bu kurala uygulanıyor.

Paket java.utilve sınıf adı Optionalbölündüğünden, bu yapının yürütmeyi bozmaması derlenmiş koda baktığımızda görülebilir 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.OptionalDe- / derlemek için minimal bir örnek almak için Guava kodunu kopyaladığım yerel bir sınıftır)

Gördüğünüz gibi, ek açıklama artık mevcut değil. Derleyici için, yöntem null döndürdüğünde (ve kaynak kodu okuyucular için bir ipucu) bir uyarıyı önlemek için yalnızca bir işaretleyicidir, ancak derlenmiş koda dahil edilmeyecektir.


Bu derleyici hatası aşağıdaki gibi değişkenler için de geçerlidir:

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

Ancak, ek açıklama ElementType.FIELDaynı JLS yan tümcesinde yazıldığı gibi ek olarak hedef türü aldığında kabul edilebilir olabilir :

TA ek olarak meta açıklamalı olarak eklenmişse @Target(ElementType.FIELD), bu terim @TA java.lang.Objecthem alan bildirimi hem de alan bildirimi gibi tür bağlamları olan konumlarda yasaldır @TA java.lang.Object f;. Burada, ta alan bildirimi bağlamında TA uygulanabilir olduğundan, @TA f bildirimine (java.lang.Object türüne değil) uygulanacaktır.


11

Ek açıklamaları kullanırken, bu, import deyimi eklemek yerine tür için tam olarak nitelenmiş bir ad yazmak istediğinizde kullanılan sözdizimidir.

Dama çerçevesi kılavuzundan alıntı :

Tam nitelenmiş bir tür adına ek açıklama yazmak için doğru Java sözdizimi, ek açıklamayı java.util'de olduğu gibi basit ad kısmına koymaktır. @ Nullable List. Ancak, içe aktarma java.util.List dosyasını kaynak dosyanıza eklemek genellikle daha iyidir, böylece @Nullable List yazabilirsiniz.

Ayrıca buradan indirebileceğiniz JSR308 spesifikasyonunun 2. sayfasında da belirtilmiştir . Diyor ki:

@NonNull String veya java.lang'da olduğu gibi, türün basit adından önce bir tür ek açıklaması görünür. @ NonNull String.


6

Buradaki garip bit gerçekten ElementType.TYPE_USE-hedefli bir açıklama uygulamak için alışılmadık bir sözdizimi . Nullable 'ın belgelerini kontrol ederseniz , bilmediğiniz hedefi görürsünüz:

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

Bu açıklama, aşağıdakilerin her ikisinde de olduğu gibi, açıklamalı türün basit adından hemen önce kullanılır:

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

Bu tür bir hedefin kullanımının ne olduğunu bilmiyordum, bu yüzden hızlı bir okumadan sonra, bu hedefe sahip bir ek açıklama kullanarak dönüş türü meta verilerini alan bu basit örneğe ulaştım:

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

Ve kullanarak işledi:

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

Eminim dama çerçeve gibi birçok yararlı çerçeve, ElementType.TYPE_USE

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.