Sök…


Introduktion

I Java är en kommentar en form av syntaktiska metadata som kan läggas till Java-källkoden. Den tillhandahåller data om ett program som inte ingår i själva programmet. Anteckningar har ingen direkt effekt på hur koden de kommenterar fungerar. Klasser, metoder, variabler, parametrar och paket får antecknas.

Syntax

  • @AnnotationName // 'Marker annotation' (inga parametrar)
  • @AnnotationName (someValue) // ställer in parameter med namnet 'värde'
  • @AnnotationName (param1 = value1) // namngivna parameter
  • @AnnotationName (param1 = value1, param2 = value2) // flera namngivna parametrar
  • @AnnotationName (param1 = {1, 2, 3}) // namngiven array-parameter
  • @AnnotationName ({value1}) // matris med enstaka element som parameter med namnet 'värde'

Anmärkningar

Parametertyper

Endast konstanta uttryck av följande typer är tillåtna för parametrar såväl som matriser av dessa typer:

  • String
  • Class
  • primitiva typer
  • Enumtyper
  • Annotationstyper

Inbyggda kommentarer

Standardversionen av Java kommer med några fördefinierade kommentarer. Du behöver inte definiera dem själv och du kan använda dem omedelbart. De tillåter kompilatorn att möjliggöra en grundläggande kontroll av metoder, klasser och kod.

@Åsidosätta

Den här anteckningen gäller en metod och säger att den här metoden måste åsidosätta en superklass-metod eller implementera en abstrakt superklass-metoddefinition. Om denna kommentar används med någon annan typ av metod, kommer kompilatorn att kasta ett fel.

Betong superklass

public class Vehicle {
   public void drive() {
        System.out.println("I am driving");
   }
}

class Car extends Vehicle {
    // Fine
    @Override
    public void drive() {
        System.out.prinln("Brrrm, brrm");
    }
}

Abstrakt klass

abstract class Animal  {
   public abstract void makeNoise(); 
}

class Dog extends Animal {
    // Fine
    @Override
    public void makeNoise() {
        System.out.prinln("Woof");
    }
}

Fungerar inte

class Logger1 {
    public void log(String logString) {
        System.out.prinln(logString);
    }
}

class Logger2 {
    // This will throw compile-time error. Logger2 is not a subclass of Logger1. 
    // log method is not overriding anything
    @Override
    public void log(String logString) {
        System.out.println("Log 2" + logString);
    }
}

Det huvudsakliga syftet är att fånga in felaktig typ, där du tror att du åsidosätter en metod, men faktiskt definierar en ny.

class Vehicle {
   public void drive() {
        System.out.println("I am driving");
   }
}

class Car extends Vehicle {
    // Compiler error. "dirve" is not the correct method name to override.
    @Override
    public void dirve() {
        System.out.prinln("Brrrm, brrm");
    }
}

Observera att betydelsen av @Override har förändrats över tid:

  • I Java 5 betydde det att den antecknade metoden var tvungen att åsidosätta en icke-abstrakt metod som deklarerats i superklasskedjan.
  • Från Java 6 och framåt är det också nöjd om den antecknade metoden implementerar en abstrakt metod som deklareras i klasserna superklass / gränssnittshierarki.

(Detta kan ibland orsaka problem när du backar portkoden till Java 5.)

@Deprecated

Detta markerar metoden som avskrivet. Det kan finnas flera skäl till detta:

  • API är bristfälligt och är opraktiskt att fixa,

  • användning av API kommer sannolikt att leda till fel,

  • API har ersatts av ett annat API,

  • API är föråldrad,

  • API är experimentellt och är föremål för oförenliga förändringar,

  • eller någon kombination av ovanstående.

Det specifika skälet till avskrivning finns vanligtvis i dokumentationen för API: n.


Annotationen får kompilatorn att avge ett fel om du använder den. IDE: er kan också lyfta fram den här metoden på något sätt som föråldrad

class ComplexAlgorithm {
    @Deprecated
    public void oldSlowUnthreadSafeMethod() {
        // stuff here
    }
    
    public void quickThreadSafeMethod() {
        // client code should use this instead
    }
}

@SuppressWarnings

I nästan alla fall, när kompilatorn avger en varning, är den lämpligaste åtgärden att fixa orsaken. I vissa fall (till exempel Generics-kod med exempelvis säker-säker pre-generics-kod) är detta kanske inte möjligt och det är bättre att undertrycka de varningar du förväntar dig och inte kan fixa, så att du tydligare kan se oväntade varningar.

Denna kommentar kan tillämpas på en hel klass, metod eller rad. Det tar kategorin av varning som en parameter.

@SuppressWarnings("deprecation")
public class RiddledWithWarnings {
    // several methods calling deprecated code here
}

@SuppressWarning("finally")
public boolean checkData() {
    // method calling return from within finally block
}

Det är bättre att begränsa kommentarens omfattning så mycket som möjligt för att förhindra att oväntade varningar också undertrycks. Till exempel begränsa annoteringens räckvidd till en enda rad:

ComplexAlgorithm algorithm = new ComplexAlgorithm();
@SuppressWarnings("deprecation") algoritm.slowUnthreadSafeMethod(); 
// we marked this method deprecated in an example above

@SuppressWarnings("unsafe") List<Integer> list = getUntypeSafeList(); 
// old library returns, non-generic List containing only integers

Varningarna som stöds av denna kommentar kan variera från kompilator till kompilator. Endast de unchecked och deprecation nämns specifikt i JLS. Oigenkända varningstyper ignoreras.

@SafeVarargs

På grund av radering av typ omvandlas void method(T... t) till void method(Object[] t) betyder att kompilatorn inte alltid kan verifiera att användningen av vargar är typsäker. Till exempel:

private static <T> void generatesVarargsWarning(T... lists) {

Det finns fall där användningen är säker, i vilket fall du kan kommentera metoden med SafeVarargs anteckningen för att undertrycka varningen. Detta döljer uppenbarligen varningen om din användning också är osäker.

@FunctionalInterface

Detta är en valfri annotation som används för att markera en FunctionalInterface. Det kommer att få kompilatorn att klaga om den inte överensstämmer med FunctionalInterface-specifikationen (har en enda abstrakt metod)

@FunctionalInterface
public interface ITrade {
  public boolean check(Trade t);
}

@FunctionalInterface
public interface Predicate<T> {
  boolean test(T t);
}

Runtime-kommentarer kontrolleras via reflektion

Java's Reflection API låter programmeraren utföra olika kontroller och operationer på klassfält, metoder och kommentarer under körning. För att en kommentar ska kunna synas vid körning måste RetentionPolicy ändras till RUNTIME , vilket visas i exemplet nedan:

@interface MyDefaultAnnotation {

}

@Retention(RetentionPolicy.RUNTIME)
@interface MyRuntimeVisibleAnnotation {

}

public class AnnotationAtRuntimeTest {

    @MyDefaultAnnotation
    static class RuntimeCheck1 {
    }
    
    @MyRuntimeVisibleAnnotation
    static class RuntimeCheck2 {
    }
    
    public static void main(String[] args) {
        Annotation[] annotationsByType = RuntimeCheck1.class.getAnnotations();
        Annotation[] annotationsByType2 = RuntimeCheck2.class.getAnnotations();

        System.out.println("default retention: " + Arrays.toString(annotationsByType));
        System.out.println("runtime retention: " + Arrays.toString(annotationsByType2));
    }
}

Definiera annotationstyper

Annotationstyper definieras med @interface . Parametrar definieras liknande metoder för ett vanligt gränssnitt.

@interface MyAnnotation {
    String param1();
    boolean param2();
    int[] param3();  // array parameter 
}

Ursprungliga värden

@interface MyAnnotation {
    String param1() default "someValue";
    boolean param2() default true;
    int[] param3() default {};
}

Meta-Anteckningar

Meta-kommentarer är anteckningar som kan tillämpas på annotationstyper. Speciell fördefinierad metaanotation definierar hur annotationstyper kan användas.

@Mål

@Target begränsar de typer annotationen kan tillämpas på.

@Target(ElementType.METHOD)
@interface MyAnnotation {
    // this annotation can only be applied to methods
}

Flera värden kan läggas till med hjälp av arraynotation, t.ex. @Target({ElementType.FIELD, ElementType.TYPE})

Tillgängliga värden

ElementType mål exempel användning på målelement
ANNOTATION_TYPE annotationstyper
@Retention(RetentionPolicy.RUNTIME) 
@interface MyAnnotation
KONSTRUKTÖR konstruktörer
@MyAnnotation
public MyClass() {}
FÄLT fält, enumkonstanter
@XmlAttribute
private int count;
LOCAL_VARIABLE variabla deklarationer inom metoder
for (@LoopVariable int i = 0; i < 100; i++) {
@Unused
String resultVariable;
}
PAKET paket (i package-info.java )
@Deprecated
package very.old;
METOD metoder
@XmlElement
public int getCount() {...}
PARAMETER metod / konstruktörsparametrar
public Rectangle(
@NamedArg("width") double width,
@NamedArg("height") double height) {
...
}
TYP klasser, gränssnitt, enums
@XmlRootElement
public class Report {}
Java SE 8
ElementType mål exempel användning på målelement
TYPE_PARAMETER Skriv in parameterdeklarationer
public <@MyAnnotation T> void f(T t) {}
TYPE_USE Användning av en typ
Object o = "42";
String s = (@MyAnnotation String) o;

@Bibehållande

Meta-anteckningen @Retention definierar synligheten för anteckningen under applikationens sammanställningsprocess eller körning. Som standard ingår kommentarer i .class filer, men är inte synliga vid körning. För att göra en kommentar tillgänglig vid körning måste RetentionPolicy.RUNTIME ställas in för den annotationen.

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    // this annotation can be accessed with reflections at runtime
}

Tillgängliga värden

RetentionPolicy Effekt
KLASS Anteckningen är tillgänglig i .class filen, men inte vid körning
KÖRNING Anteckningen är tillgänglig vid körning och kan nås via reflektion
KÄLLA Anteckningen är tillgänglig vid kompileringstidpunkten, men läggs inte till i .class . Annoteringen kan t.ex. användas av en annotationsprocessor.

@Documented

Den @Documented används för att markera anteckningar vars användning bör dokumenteras av API-dokumentationsgeneratorer som javadoc . Det har inga värden. Med @Documented kommer alla klasser som använder annotationen att lista den på deras genererade dokumentationssida. Utan @Documented är det inte möjligt att se vilka klasser som använder annotationen i dokumentationen.

@Inherited

@Inherited meta-annotation är relevant för anteckningar som tillämpas på klasser. Det har inga värden. Att markera en kommentar som @Inherited ändrar sättet på vilket kommentarfrågan fungerar.

  • För en icke-ärvt kommentar undersöker frågan bara klassen som granskas.
  • För en ärvd kommentar kommer frågan också att kontrollera superklasskedjan (rekursivt) tills en instans av annotationen hittas.

Observera att endast superklasserna fråges: eventuella anteckningar kopplade till gränssnitt i klasserhierarkin ignoreras.

@Repeatable

@Repeatable meta-annotation lades till i Java 8. Det indikerar att flera instanser av annotationen kan bifogas till annotationens mål. Denna metanotation har inga värden.

Få annotationsvärden vid körning

Du kan hämta de aktuella egenskaperna för annotationen genom att använda Reflektion för att hämta metoden eller fältet eller klassen som har en kommentar tillämpad på och sedan hämta önskade egenskaper.

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    String key() default "foo";
    String value() default "bar";
}


class AnnotationExample {
    // Put the Annotation on the method, but leave the defaults
    @MyAnnotation
    public void testDefaults() throws Exception {
        // Using reflection, get the public method "testDefaults", which is this method with no args
        Method method = AnnotationExample.class.getMethod("testDefaults", null);

        // Fetch the Annotation that is of type MyAnnotation from the Method
        MyAnnotation annotation = (MyAnnotation)method.getAnnotation(MyAnnotation.class);

        // Print out the settings of the Annotation
        print(annotation);
    }

    //Put the Annotation on the method, but override the settings
    @MyAnnotation(key="baz", value="buzz")
    public void testValues() throws Exception {
        // Using reflection, get the public method "testValues", which is this method with no args
        Method method = AnnotationExample.class.getMethod("testValues", null);

        // Fetch the Annotation that is of type MyAnnotation from the Method
        MyAnnotation annotation = (MyAnnotation)method.getAnnotation(MyAnnotation.class);

        // Print out the settings of the Annotation
        print(annotation);
    }

    public void print(MyAnnotation annotation) {
        // Fetch the MyAnnotation 'key' & 'value' properties, and print them out 
        System.out.println(annotation.key() + " = " + annotation.value());
    }

    public static void main(String[] args) {
        AnnotationExample example = new AnnotationExample();
        try {
            example.testDefaults();
            example.testValues();
        } catch( Exception e ) {
            // Shouldn't throw any Exceptions
            System.err.println("Exception [" + e.getClass().getName() + "] - " + e.getMessage());
            e.printStackTrace(System.err);
        }
    }
}

Utgången kommer att vara

foo = bar
baz = buzz

Upprepande kommentarer

Tills Java 8 kunde två instanser av samma kommentar inte tillämpas på ett enda element. Standardlösningen var att använda en containeranteckning som innehöll en matris med någon annan annotation:

// Author.java
@Retention(RetentionPolicy.RUNTIME)
public @interface Author {
    String value();
}

// Authors.java
@Retention(RetentionPolicy.RUNTIME)
public @interface Authors {
    Author[] value();
}

// Test.java
@Authors({
    @Author("Mary"),
    @Author("Sam")
})
public class Test {
    public static void main(String[] args) {
        Author[] authors = Test.class.getAnnotation(Authors.class).value();
        for (Author author : authors) {
            System.out.println(author.value());
            // Output:
            // Mary
            // Sam
        }
    }
}
Java SE 8

Java 8 tillhandahåller ett renare, mer transparent sätt att använda behållaranteckningar med @Repeatable anteckningen. Först lägger vi till detta i Author :

@Repeatable(Authors.class)

Detta säger Java att behandla flera @Author kommentarer som om de var omgiven av @Authors behållaren. Vi kan också använda Class.getAnnotationsByType() att få åtkomst till @Author arrayen av sin egen klass istället för genom sin behållare:

@Author("Mary")
@Author("Sam")
public class Test {
    public static void main(String[] args) {
        Author[] authors = Test.class.getAnnotationsByType(Author.class);
        for (Author author : authors) {
            System.out.println(author.value());
            // Output:
            // Mary
            // Sam
        }
    }
}

Ärvda kommentarer

Som standard klassanteckningar gäller inte för typer som utvidgar dem. Detta kan ändras genom att lägga till @Inherited kommentaren i kommentardefinitionen

Exempel

Tänk på följande två kommentarer:

@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface InheritedAnnotationType {
}

och

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface UninheritedAnnotationType {
}

Om tre klasser kommenteras så här:

@UninheritedAnnotationType
class A {
}

@InheritedAnnotationType
class B extends A {
}

class C extends B {
}

kör den här koden

System.out.println(new A().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println(new B().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println(new C().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println("_________________________________");
System.out.println(new A().getClass().getAnnotation(UninheritedAnnotationType.class));
System.out.println(new B().getClass().getAnnotation(UninheritedAnnotationType.class));
System.out.println(new C().getClass().getAnnotation(UninheritedAnnotationType.class));

kommer att skriva ut ett resultat som liknar detta (beroende på anteckningarnas paket):

null
@InheritedAnnotationType()
@InheritedAnnotationType()
_________________________________
@UninheritedAnnotationType()
null
null

Observera att kommentarer endast kan ärvas från klasser, inte gränssnitt.

Kompilera tidsbearbetning med kommentarprocessor

Detta exempel visar hur man gör kompilering av tidskontroll av ett kommenterat element.

Anteckningen

@Setter anteckningen är en markör som kan tillämpas på metoder. Anteckningen kommer att kasseras under sammanställningen och kommer inte att finnas tillgänglig efteråt.

package annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface Setter {
}

Annotationsprocessorn

SetterProcessor används av kompilatorn för att bearbeta kommentarerna. Den kontrollerar, om de metoder som är markerade med @Setter anteckningen är public , icke- static metoder med ett namn som börjar med set och som har en stor bokstav som fjärde bokstaven. Om ett av dessa villkor inte uppfylls, skrivs ett fel till Messager . Kompilatorn skriver detta till stderr, men andra verktyg kan använda denna information annorlunda. NetBeans IDE tillåter exempelvis användaren att ange kommentarprocessorer som används för att visa felmeddelanden i redigeraren.

package annotation.processor;

import annotation.Setter;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;

@SupportedAnnotationTypes({"annotation.Setter"})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class SetterProcessor extends AbstractProcessor {

    private Messager messager;

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        // get elements annotated with the @Setter annotation
        Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(Setter.class);

        for (Element element : annotatedElements) {
            if (element.getKind() == ElementKind.METHOD) {
                // only handle methods as targets
                checkMethod((ExecutableElement) element);
            }
        }

        // don't claim annotations to allow other processors to process them
        return false;
    }

    private void checkMethod(ExecutableElement method) {
        // check for valid name
        String name = method.getSimpleName().toString();
        if (!name.startsWith("set")) {
            printError(method, "setter name must start with \"set\"");
        } else if (name.length() == 3) {
            printError(method, "the method name must contain more than just \"set\"");
        } else if (Character.isLowerCase(name.charAt(3))) {
            if (method.getParameters().size() != 1) {
                printError(method, "character following \"set\" must be upper case");
            }
        }

        // check, if setter is public
        if (!method.getModifiers().contains(Modifier.PUBLIC)) {
            printError(method, "setter must be public");
        }

        // check, if method is static
        if (method.getModifiers().contains(Modifier.STATIC)) {
            printError(method, "setter must not be static");
        }
    }

    private void printError(Element element, String message) {
        messager.printMessage(Diagnostic.Kind.ERROR, message, element);
    }

    @Override
    public void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);

        // get messager for printing errors
        messager = processingEnvironment.getMessager();
    }

}

Förpackning

För att kunna appliceras av kompilatorn måste annotationsprocessorn göras tillgänglig för SPI (se ServiceLoader ).

För att göra detta måste en textfil META-INF/services/javax.annotation.processing.Processor läggas till i burkfilen som innehåller annotationsprocessorn och anteckningen utöver de andra filerna. Filen måste innehålla det fullt kvalificerade namnet på annotationsprocessorn, dvs den ska se ut så här

annotation.processor.SetterProcessor

Vi antar att burkfilen heter AnnotationProcessor.jar nedan.

Exempel kommenterad klass

Följande klass är exempelklass i standardpaketet med anteckningar som tillämpas på korrekta element enligt lagringspolicyn. Men endast annotationsprocessorn betraktar endast den andra metoden som ett giltigt anteckningsmål.

import annotation.Setter;

public class AnnotationProcessorTest {
    
    @Setter
    private void setValue(String value) {}

    @Setter
    public void setString(String value) {}
    
    @Setter
    public static void main(String[] args) {}
    
}

Använda annotationsprocessorn med javac

Om kommentarprocessorn upptäcks med hjälp av SPI, används den automatiskt för att behandla kommenterade element. Exempelvis sammanställa klassen AnnotationProcessorTest med

javac -cp AnnotationProcessor.jar AnnotationProcessorTest.java

ger följande utgång

AnnotationProcessorTest.java:6: error: setter must be public
    private void setValue(String value) {}
                 ^
AnnotationProcessorTest.java:12: error: setter name must start with "set"
    public static void main(String[] args) {}
                       ^
2 errors

istället för att sammanställa normalt. Ingen .class skapas.

Detta kan förhindras genom att ange -proc:none alternativ för javac . Du kan också avstå från den vanliga sammanställningen genom att ange -proc:only istället.

IDE-integration

Netbeans

Annotationsprocessorer kan användas i NetBeans-redigeraren. För att göra detta måste annotationsprocessorn anges i projektinställningarna:

  1. gå till Project Properties > Build > Compiling

  2. lägg till kryssmarkeringar för Enable Annotation Processing och Enable Annotation Processing in Editor

  3. Klicka på Add bredvid listan med kommentarerna

  4. i popup-fönstret som visas anger du det fullt kvalificerade klassnamnet för annotationsprocessorn och klickar på Ok .

Resultat

Redigeringsfönster med anpassat felmeddelande

Idén bakom kommentarer

Java Language Specification beskriver kommentarer på följande sätt:

En kommentar är en markör som associerar information med ett programkonstrukt, men har ingen effekt vid körtid.

Kommentarer kan förekomma före typer eller deklarationer. Det är möjligt för dem att visas på en plats där de kan gälla både för en typ eller en deklaration.
Vad exakt en kommentar gäller för regleras av " @Target " @Target . Se "Definiera annotationstyper" för mer information.

Anteckningar används för en mängd syften. Ramar som Spring och Spring-MVC använder anteckningar för att definiera var beroenden ska injiceras eller var förfrågningar ska dirigeras.

Andra ramverk använder anteckningar för kodgenerering. Lombok och JPA är främsta exempel som använder anteckningar för att generera Java (och SQL) -kod.

Detta ämne syftar till att ge en omfattande översikt av:

  • Hur definierar du dina egna kommentarer?

  • Vilka kommentarer ger Java-språket?

  • Hur används anteckningar i praktiken?

Anteckningar för "detta" och mottagarparametrar

När Java-anteckningar först introducerades fanns det ingen möjlighet att kommentera målet för en instansmetod eller den dolda konstruktörsparametern för en konstruktör för inre klasser. Detta åtgärdades i Java 8 med tillägg av mottagarparameterdeklarationer ; se JLS 8.4.1 .

Mottagarparametern är en valfri syntaktisk enhet för en instansmetod eller en inre klassens konstruktör. För en instansmetod representerar mottagarparametern objektet för vilket metoden åberopas. För en inre klassens konstruktör representerar mottagarparametern den omedelbart omslutande instansen för det nybyggda objektet. I vilket fall som helst existerar mottagarparametern enbart för att tillåta typen av det representerade objektet att anges i källkod, så att typen kan antecknas. Mottagarparametern är inte en formell parameter; mer exakt, det är inte en deklaration av någon form av variabel (§4.12.3), den är aldrig bunden till något värde som överförs som ett argument i ett metodkallningsuttryck eller ett kvalificerat uttryck för klassinstans, och det har ingen som helst effekt på körtid.

Följande exempel illustrerar syntaxen för båda typerna av mottagarparameter:

public class Outer {
    public class Inner {
        public Inner (Outer this) {
           // ...
        }
        public void doIt(Inner this) {
           // ...
        }
    }
}

Det enda syftet med mottagarparametrarna är att låta dig lägga till kommentarer. Du kan till exempel ha en anpassad kommentar @IsOpen vars syfte är att hävda att ett Closeable objekt inte har stängts när en metod kallas. Till exempel:

public class MyResource extends Closeable {
    public void update(@IsOpen MyResource this, int value) {
        // ...
    }

    public void close() {
        // ...
    }
}

På en nivå kan @IsOpen anteckningen på this helt enkelt fungera som dokumentation. Men vi kan potentiellt göra mer. Till exempel:

  • En kommentarprocessor kan infoga en körtidskontroll om att this inte är i stängt tillstånd när update anropas.
  • En kodkontroll kan utföra en statisk kodanalys för att hitta fall där this kan stängas när update anropas.

Lägg till flera kommentarvärden

En annotationsparameter kan acceptera flera värden om den definieras som en matris. Till exempel definieras standardanteckningen @SuppressWarnings :

public @interface SuppressWarnings {
    String[] value();
}

Det value parametern är en array av strängar. Du kan ställa in flera värden genom att använda en notation liknande Array initializers:

@SuppressWarnings({"unused"})
@SuppressWarnings({"unused", "javadoc"})

Om du bara behöver ställa in ett enda värde kan parenteserna utelämnas:

@SuppressWarnings("unused") 


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow