English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In dieser Anleitung lernen wir anhand von Beispielen verschiedene Arten von Java-Annotierung.
Java-Annotierung ist Meta-Daten unserer Programmsource (Daten über Daten). Java SE bietet mehrere vorgegebene Annotierungstypen. Darüber hinaus können wir nach Bedarf benutzerdefinierte Annotierungstypen erstellen.
Wenn Sie nicht wissen, was eine Annotierung ist, besuchen Sie bitteJava AnnotationsAnleitung.
Diese Annotatționstypen können in die folgenden Kategorien eingeteilt werden:
1. Vorgegebene Annotatționstypen
@Deprecated
@Override
@Verzweigungsfehler unterdrücken
@SafeVarargs
@FunctionalInterface
2. 自定义注解
3. 元注解
@Behalten
@Documented
@Ziel
@Inherited
@Wiederholbar
@Veraltet-Aufruf ist eine Markierungsaufrufmarke, die angibt, dass ein Element (Klasse, Methode, Feld usw.) veraltet ist und durch ein aktualisiertes Element ersetzt wurde.
其语法为:
@Deprecated Zugriffsmodifikator Rückgabetyp veraltetemMethodennamen() { ... }
Wenn ein Programm veraltete Elemente verwendet, generiert der Compiler Warnungen.
Wir verwenden die Javadoc @veraltet-Marke, um veraltete Elemente zu dokumentieren.
/** * @veraltet * Warum wurde es veraltet? */ @Deprecated Zugriffsmodifikator Rückgabetyp veraltetemMethodennamen() { ... }
class Main { /** * @veraltet * Diese Methode ist veraltet und wurde durch newMethod() ersetzt. */ @Deprecated public static void deprecatedMethod() { System.out.println("Veraltete Methode"); } public static void main(String args[]) { deprecatedMethod(); } }
输出结果
Veraltete Methode
@Override-Annotierung gibt an, dass die Methode einer Unterklasse mit dem gleichen Methodennamen, Rückgabetyp und Parameterliste die Methode der Überklasse überschreibt.
@Override ist bei der Überschreibung von Methoden nicht zwingend erforderlich. Wenn jedoch verwendet, gibt der Compiler bei Fehlern (z.B. falscher Parameter-Typ) eine Fehlermeldung aus.
class Animal { //Methode überschreiben public void display(){ System.out.println("Ich bin ein Tier"); } } class Dog extends Animal { //Methode überschreiben @Override public void display(){ System.out.println("Ich bin ein Hund"); } public void printMessage(){ display(); } } class Main { public static void main(String[] args) { Dog dog1 = new Dog(); dog1.printMessage(); } }
输出结果
Ich bin ein Hund
In diesem Beispiel wird durch Erstellen eines Objekts der Klasse Dog namens dog1,können wir ihre Methode printMessage() aufrufen, und diese Methode führt dann den display()-Befehl aus.
Da display() in beiden Klassen definiert ist, überschreibt die display()-Methode der Dog-Unterklasse die display()-Methode der Superklasse Animal. Daher wird die Methode der Unterklasse aufgerufen.
Wie der Name schon sagt, zeigt die @SuppressWarnings-Annotation dem Compiler an, dass bei der Ausführung des Programms keine Warnungen generiert werden sollen.
Wir können die zu deaktivierenden Warnungstypen angeben. Warnungen sind spezifisch für den Compiler, aber sie werden in zwei Kategorien unterteilt:veraltet und Nicht überprüft.
Um das Anzeigen spezifischer Kategorien von Warnungen zu unterdrücken, verwenden wir absichtlich:
@SuppressWarnings("warningCategory")
例如,
@SuppressWarnings("deprecated")
Um das Anzeigen mehrerer Kategorien von Warnungen zu unterdrücken, verwenden wir absichtlich:
@SuppressWarnings("warningCategory"1", "warningCategory2"}
例如,
@SuppressWarnings({"deprecated", "unchecked"})
Wenn wir Elemente verwenden, die nicht empfohlen werden, zeigt die Kategorie deprecated dem Compiler an, dass Warnungen unterdrückt werden sollen.
wenn wir primitiven Typen verwenden, zeigt der unchecked-Kategoriehinweis dem Compiler an, dass Warnungen nicht angezeigt werden sollen.
Und, nicht definierte Warnungen werden ignoriert. Zum Beispiel,
@SuppressWarnings("someundefinedwarning")
class Main { @Deprecated public static void deprecatedMethod() { System.out.println("Veraltete Methode"); } @SuppressWarnings("deprecated") public static void main(String args[]) { Main depObj = new Main(); depObj. deprecatedMethod(); } }
输出结果
Veraltete Methode
Hier ist deprecatedMethod() als veraltet markiert, und es wird eine Compilerwarnung ausgegeben, wenn sie verwendet wird. Durch die Verwendung der @SuppressWarnings("deprecated") Annotierung können wir die Compilerwarnung vermeiden.
@SafeVarargs Annotierung behauptet, dass der mit der Annotierung versehene Methoden oder Konstruktor keine unsicheren Operationen auf seinen Variablenparameter (veränderlichen Parameter) ausführt.
können wir diese Annotierung nur auf Methoden oder Konstruktoren anwenden, die nicht überschrieben werden können. Dies liegt daran, dass das Überschreiben dieser Methoden möglicherweise unsichere Operationen ausführt.
In Java 9Bisher konnten wir diese Annotierung nur auf final oder static Methoden anwenden, da sie nicht überschrieben werden können. Jetzt können wir diese Annotierung auch auf private Methoden anwenden.
import java.util.*; class Main { private void displayList(List<String>... lists) { for (List<String> list : lists) { System.out.println(list); } } public static void main(String args[]) { Main obj = new Main(); List<String> universityList = Arrays.asList("Tribhuvan University", "Kathmandu University"); obj.displayList(universityList); List<String> programmingLanguages = Arrays.asList("Java", "C"); obj.displayList(universityList, programmingLanguages); } }
Warnhinweise
Typsicherheit: Potenzielle Heap-Verschmutzung über varargs-Parameterlisten Typsicherheit: Ein generisches Array von List<String> wird für ein varargs erstellt Parameter
输出结果
Hinweis: Main.java verwendet nicht überprüfte oder unsichere Operationen. [Tribhuvan University, Kathmandu University] [Tribhuvan University, Kathmandu University] [Java, C]
Hier wird das Variable-Length-Argument List ... list als Typ List spezifiziert. Dies bedeutet, dass die Methode displayList() null oder mehrere Parameter haben kann.
Der obige Programmcode kompiliert ohne Fehler, aber gibt eine Warnung aus, wenn die @SafeVarargs-Annotation nicht verwendet wird.
Beim Verwenden der @SafeVarargs-Annotation im obigen Beispiel
@SafeVarargs private void displayList(List<String>... lists) { ... }
Wir erhalten denselben Ausgabe, aber ohne Warnungen. Wenn diese Annotation verwendet wird, werden auch unbeaufsichtigte Warnungen entfernt.
Java 8Zunächst wurde diese @FunctionalInterface-Annotation eingeführt. Diese Annotation zeigt an, dass der Typ, auf den sie angewendet wird, ein funktionaler Interface ist. Ein funktionaler Interface kann nur eine abstrakte Methode haben.
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); //Dies ist eine abstrakte Methode }
Wenn wir eine weitere abstrakte Methode hinzufügen, dann
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); // Dies ist eine abstrakte Methode public void secondMethod(); //Dies verursacht einen Compilerfehler }
Jetzt, wenn wir das Programm ausführen, erhalten wir folgende Warnungen:
Unerwartete @FunctionalInterface-Annotation @FunctionalInterface ^ MyFuncInterface ist kein funktionaler Interface mehrere nicht-Überschreibende abstrakte Methoden, die im Interface MyFuncInterface gefunden werden
使用@FunctionalInterface注解不是强制性的。编译器会将满足功能接口定义的任何接口视为功能接口。
我们使用此注解的目的,是确保功能接口只有一种抽象方法。
但是,它可以有任意数量的默认方法和静态方法,因为它们都有实现。
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); //这是一种抽象方法 default void secondMethod() { ... } default void thirdMethod() { ... } }
也可以创建我们自己的自定义注解。
其语法为:
[访问修饰符] @interface<AnnotationName> { DataType <MethodName>() [default value]; }
这是您需要了解的有关自定义注解的信息:
注解可以通过使用@interface后面跟注解名称来创建。
注解可以具有看起来像方法的元素,但是它们没有实现。
默认值是可选的。参数不能为空值。
方法的返回类型可以是原始类型,枚举,字符串,类名或这些类型的数组。
@interface MyCustomAnnotation { String value() default "default value"; } class Main { @MyCustomAnnotation(value = "w3codebox) public void method1() { System.out.println("测试方法1); } public static void main(String[] args) throws Exception { Main obj = new Main(); obj.method1(); } }
输出结果
测试方法1
元注解是应用于其他注解的注解。
@Retention注解指定了该注解可用的最高级别。
其语法为:
@Retention(RetentionPolicy)
有三种类型:
RetentionPolicy.SOURCE - 注释仅在源级别可用,并且被编译器忽略。
RetentionPolicy.CLASS - 注解在编译时可供编译器使用,但Java虚拟机(JVM)会忽略它。
RetentionPolicy.RUNTIME - 注解可用于JVM。
例如,
@Retention(RetentionPolicy.RUNTIME) public @interface MyCustomAnnotation{ ... }
默认情况下,自定义注解不包含在官方Java文档中。要将注解包含在Javadoc文档中,请使用@Documented注解。
例如,
@Documented public @interface MyCustomAnnotation{ ... }
我们可以使用@Target注解将注解限制为应用于特定目标。
其语法为:
@Target(ElementType)
ElementType可有以下几种类型之一:
元素类型 | Target |
---|---|
ElementType.ANNOTATION_TYPE | 注解类型 |
ElementType.CONSTRUCTOR | 构造函数 |
ElementType.FIELD | 字段 |
ElementType.LOCAL_VARIABLE | 局部变量 |
ElementType.METHOD | 方法 |
ElementType.PACKAGE | 包 |
ElementType.PARAMETER | 参数 |
ElementType.TYPE | 用于描述类、接口(包括注解类型)或enum声明 |
例如,
@Target(ElementType.METHOD) public @interface MyCustomAnnotation{ ... }
在此示例中,我们仅将此注解的使用限制为方法。
注意:如果未定义目标类型,则注解可用于任何元素。
默认情况下,注解类型不能从超类继承。但是,如果需要将注解从超类继承到子类,则可以使用@Inherited注解。
其语法为:
@Inherited
例如,
@Inherited public @interface MyCustomAnnotation { ... } @MyCustomAnnotation public class ParentClass{ ... } public class ChildClass extends ParentClass { ... }
带有@Repeatable标记的注解可以多次应用于同一声明。
@Repeatable(Universities.class)} public @interface University { String name(); }
Der Wert in der @Repeatable Annotation ist ein Container-Annotation. Container-Annotations haben den Variablenwert (value) des obigen wiederverwendbaren Annotation-Arrays. Hierbei ist Universities der Container, der Annotions-Typen enthält.
public @interface Universities { University[] value(); }
Jetzt kann die @University Annotation auf derselben Deklaration mehrmals verwendet werden.
@University(name = "TU") @University(name = "KU") private String uniName;
Wenn Sie Annottionsdaten abrufen müssen, können SieReflection.
Um den Wert einer Annotation abzurufen, verwenden wir die Methoden getAnnotationsByType() oder getAnnotations() aus dem Reflection API.