Java中的注解
注释用于提供有关程序的补充信息。
- 注释以“ @ ”开头。
- 注释不会改变已编译程序的操作。
- 注释有助于将元数据(信息)与程序元素相关联,即实例变量、构造函数、方法、类等。
- 注释不是纯粹的注释,因为它们可以改变编译器处理程序的方式。例如,请参见下面的代码。
- 注释基本上用于提供附加信息,因此可以替代 XML 和Java标记接口。
Java中的注解层次结构
执行:
Note: This program throws compiler error because we have mentioned override, but not overridden, we have overloaded display.
例子:
Java
// Java Program to Demonstrate that Annotations
// are Not Barely Comments
// Class 1
class Base {
// Method
public void display()
{
System.out.println("Base display()");
}
}
// Class 2
// Main class
class Derived extends Base {
// Overriding method as already up in above class
@Override public void display(int x)
{
// Print statement when this method is called
System.out.println("Derived display(int )");
}
// Method 2
// Main driver method
public static void main(String args[])
{
// Creating object of this class inside main()
Derived obj = new Derived();
// Calling display() method inside main()
obj.display();
}
}
Java
// Java Program to Demonstrate Type Annotation
// Importing required classes
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
// Using target annotation to annotate a type
@Target(ElementType.TYPE_USE)
// Declaring a simple type annotation
@interface TypeAnnoDemo{}
// Main class
public class GFG {
// Main driver method
public static void main(String[] args) {
// Annotating the type of a string
@TypeAnnoDemo String string = "I am annotated with a type annotation";
System.out.println(string);
abc();
}
// Annotating return type of a function
static @TypeAnnoDemo int abc() {
System.out.println("This function's return type is annotated");
return 0;
}
}
Java
// Java Program to Demonstrate a Repeatable Annotation
// Importing required classes
import java.lang.annotation.Annotation;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
// Make Words annotation repeatable
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(MyRepeatedAnnos.class)
@interface Words
{
String word() default "Hello";
int value() default 0;
}
// Create container annotation
@Retention(RetentionPolicy.RUNTIME)
@interface MyRepeatedAnnos
{
Words[] value();
}
public class Main {
// Repeat Words on newMethod
@Words(word = "First", value = 1)
@Words(word = "Second", value = 2)
public static void newMethod()
{
Main obj = new Main();
try {
Class> c = obj.getClass();
// Obtain the annotation for newMethod
Method m = c.getMethod("newMethod");
// Display the repeated annotation
Annotation anno
= m.getAnnotation(MyRepeatedAnnos.class);
System.out.println(anno);
}
catch (NoSuchMethodException e) {
System.out.println(e);
}
}
public static void main(String[] args) { newMethod(); }
}
Java
public class DeprecatedTest
{
@Deprecated
public void Display()
{
System.out.println("Deprecatedtest display()");
}
public static void main(String args[])
{
DeprecatedTest d1 = new DeprecatedTest();
d1.Display();
}
}
Java
// Java Program to Illustrate Override Annotation
// Class 1
class Base
{
public void Display()
{
System.out.println("Base display()");
}
public static void main(String args[])
{
Base t1 = new Derived();
t1.Display();
}
}
// Class 2
// Extending above class
class Derived extends Base
{
@Override
public void Display()
{
System.out.println("Derived display()");
}
}
Java
// Java Program to illustrate SuppressWarnings Annotation
// Class 1
class DeprecatedTest
{
@Deprecated
public void Display()
{
System.out.println("Deprecatedtest display()");
}
}
// Class 2
public class SuppressWarningTest
{
// If we comment below annotation, program generates
// warning
@SuppressWarnings({"checked", "deprecation"})
public static void main(String args[])
{
DeprecatedTest d1 = new DeprecatedTest();
d1.Display();
}
}
Java
// Java Program to Demonstrate User-defined Annotations
package source;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
// User-defined annotation
@Documented
@Retention(RetentionPolicy.RUNTIME)
@ interface TestAnnotation
{
String Developer() default "Rahul";
String Expirydate();
} // will be retained at runtime
// Driver class that uses @TestAnnotation
public class Test
{
@TestAnnotation(Developer="Rahul", Expirydate="01-10-2020")
void fun1()
{
System.out.println("Test method 1");
}
@TestAnnotation(Developer="Anil", Expirydate="01-10-2021")
void fun2()
{
System.out.println("Test method 2");
}
public static void main(String args[])
{
System.out.println("Hello");
}
}
输出:
10: error: method does not override or implement
a method from a supertype
如果我们删除参数 (int x) 或删除 @override,程序编译得很好。
注释的类别
列出的注释大致分为 5 类:
- 标记注释
- 单值注解
- 完整注释
- 类型注释
- 重复注释
让我们讨论一下,如果需要,我们将在需要的地方附加代码。
第 1 类:标记注释
唯一的目的是标记一个声明。这些注释不包含任何成员,也不包含任何数据。因此,它作为注释的存在就足够了。由于标记接口不包含任何成员,因此只需确定它是否存在就足够了。 @Override是标记注释的一个示例。
例子
@TestAnnotation()
类别 2:单值注释
这些注释只包含一个成员,并允许以简写形式指定成员的值。我们只需要在应用注解时指定该成员的值,不需要指定成员的名称。然而,为了使用这个速记,成员的名字必须是一个值。
例子
@TestAnnotation(“testing”);
第 3 类:完整注释
这些注释由多个数据成员、名称、值、对组成。
例子
@TestAnnotation(owner=”Rahul”, value=”Class Geeks”)
第 4 类:类型注释
这些注释可以应用于任何使用类型的地方。例如,我们可以注释方法的返回类型。这些是用@Target注释声明的。
例子
Java
// Java Program to Demonstrate Type Annotation
// Importing required classes
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
// Using target annotation to annotate a type
@Target(ElementType.TYPE_USE)
// Declaring a simple type annotation
@interface TypeAnnoDemo{}
// Main class
public class GFG {
// Main driver method
public static void main(String[] args) {
// Annotating the type of a string
@TypeAnnoDemo String string = "I am annotated with a type annotation";
System.out.println(string);
abc();
}
// Annotating return type of a function
static @TypeAnnoDemo int abc() {
System.out.println("This function's return type is annotated");
return 0;
}
}
I am annotated with a type annotation
This function's return type is annotated
第 5 类:重复注释
这些是可以多次应用于单个项目的注释。要使注解可重复,必须使用@Repeatable注解进行注解,该注解在Java.lang.annotation包中定义。它的值字段指定可重复注释的容器类型。容器被指定为一个注解,其值字段是一个可重复注解类型的数组。因此,要创建可重复的注解,首先要创建容器注解,然后将注解类型指定为@Repeatable 注解的参数。
例子:
Java
// Java Program to Demonstrate a Repeatable Annotation
// Importing required classes
import java.lang.annotation.Annotation;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
// Make Words annotation repeatable
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(MyRepeatedAnnos.class)
@interface Words
{
String word() default "Hello";
int value() default 0;
}
// Create container annotation
@Retention(RetentionPolicy.RUNTIME)
@interface MyRepeatedAnnos
{
Words[] value();
}
public class Main {
// Repeat Words on newMethod
@Words(word = "First", value = 1)
@Words(word = "Second", value = 2)
public static void newMethod()
{
Main obj = new Main();
try {
Class> c = obj.getClass();
// Obtain the annotation for newMethod
Method m = c.getMethod("newMethod");
// Display the repeated annotation
Annotation anno
= m.getAnnotation(MyRepeatedAnnos.class);
System.out.println(anno);
}
catch (NoSuchMethodException e) {
System.out.println(e);
}
}
public static void main(String[] args) { newMethod(); }
}
@MyRepeatedAnnos(value={@Words(value=1, word="First"), @Words(value=2, word="Second")})
预定义/标准注释
正如我们在层次图中看到的那样, Java普遍定义了七个内置注释。
- 从Java.lang.annotation导入了四个:@Retention、@ Documented 、 @Target和@Inherited 。
- Java.lang 中包含三个: @Deprecated、@ Override 和@SuppressWarnings
注释 1: @Deprecated
- 它是一个标记注释。它表示声明已过时并已被更新的形式取代。
- 当元素已被弃用时,应使用 Javadoc @deprecated 标记。
- @deprecated 标签用于文档,@Deprecated 注释用于运行时反射。
- 当两者一起使用时,@deprecated 标签的优先级高于 @Deprecated 注解。
例子:
Java
public class DeprecatedTest
{
@Deprecated
public void Display()
{
System.out.println("Deprecatedtest display()");
}
public static void main(String args[])
{
DeprecatedTest d1 = new DeprecatedTest();
d1.Display();
}
}
Deprecatedtest display()
注释 2:@Override
它是一个标记注释,只能用于方法。使用@Override注解的方法必须覆盖超类中的方法。如果没有,将导致编译时错误(例如,请参阅this)。它用于确保超类方法实际上被覆盖,而不是简单地重载。
例子
Java
// Java Program to Illustrate Override Annotation
// Class 1
class Base
{
public void Display()
{
System.out.println("Base display()");
}
public static void main(String args[])
{
Base t1 = new Derived();
t1.Display();
}
}
// Class 2
// Extending above class
class Derived extends Base
{
@Override
public void Display()
{
System.out.println("Derived display()");
}
}
Derived display()
注释 3:@SuppressWarnings
它用于通知编译器抑制指定的编译器警告。要抑制的警告由名称以字符串形式指定。这种类型的注释可以应用于任何类型的声明。
Java将警告分为两类。它们已被弃用且未经检查。当遗留代码与使用泛型的代码接口时,会生成任何未经检查的警告。
例子:
Java
// Java Program to illustrate SuppressWarnings Annotation
// Class 1
class DeprecatedTest
{
@Deprecated
public void Display()
{
System.out.println("Deprecatedtest display()");
}
}
// Class 2
public class SuppressWarningTest
{
// If we comment below annotation, program generates
// warning
@SuppressWarnings({"checked", "deprecation"})
public static void main(String args[])
{
DeprecatedTest d1 = new DeprecatedTest();
d1.Display();
}
}
Deprecatedtest display()
注释 4:@Documented
它是一个标记界面,告诉工具要记录注释。注释不包含在“Javadoc”注释中。在代码中使用@Documented 注释使Javadoc 等工具能够对其进行处理,并将注释类型信息包含在生成的文档中。
注释 5:@Target
它被设计为仅用作另一个注释的注释。 @Target接受一个参数,该参数必须是ElementType枚举中的常量。此参数指定可以应用注释的声明类型。下面显示了常量以及它们对应的声明类型。Target Constant Annotations Can Be Applied To ANNOTATION_TYPE Another annotation CONSTRUCTOR Constructor FIELD Field LOCAL_VARIABLE Local variable METHOD Method PACKAGE Package PARAMETER Parameter TYPE Class, Interface, or enumeration
我们可以在@Target注释中指定这些值中的一个或多个。要指定多个值,我们必须在大括号分隔的列表中指定它们。例如,要指定注解仅适用于字段和局部变量,您可以使用此@Target 注解: @Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE}) @Retention Annotation它确定注解保留在何处以及保留多长时间. @Retention 注释可以具有的 3 个值:
- SOURCE:注解将保留在源代码级别并被编译器忽略。
- CLASS:注解将在编译时保留并被 JVM 忽略。
- RUNTIME:这些将在运行时保留。
注释 6: @Inherited
@Inherited 是一个标记注解,只能用于注解声明。它只影响将在类声明中使用的注释。 @Inherited使超类的注解被子类继承。因此,当向子类发出对特定注释的请求时,如果子类中不存在该注释,则检查其超类。如果该注解存在于超类中,并且如果它使用@Inherited 进行注解,则该注解将被返回。
注解7:用户自定义(Custom)
用户定义的注释可用于注释程序元素,即变量、构造函数、方法等。这些注释可以在元素(构造函数、方法、类等)声明之前应用。
语法:声明
[Access Specifier] @interface
{
DataType () [default value];
}
在实现用户定义的注释之前,请务必将这些特定点作为自定义注释的规则。
- AnnotationName是一个接口。
- 参数不应与方法声明相关联,并且throws子句不应与方法声明一起使用。
- 参数不会有空值,但可以有默认值。
- 默认值是可选的。
- 方法的返回类型应该是原始、枚举、字符串、类名或原始数组、枚举、字符串或类名类型。
例子:
Java
// Java Program to Demonstrate User-defined Annotations
package source;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
// User-defined annotation
@Documented
@Retention(RetentionPolicy.RUNTIME)
@ interface TestAnnotation
{
String Developer() default "Rahul";
String Expirydate();
} // will be retained at runtime
// Driver class that uses @TestAnnotation
public class Test
{
@TestAnnotation(Developer="Rahul", Expirydate="01-10-2020")
void fun1()
{
System.out.println("Test method 1");
}
@TestAnnotation(Developer="Anil", Expirydate="01-10-2021")
void fun2()
{
System.out.println("Test method 2");
}
public static void main(String args[])
{
System.out.println("Hello");
}
}
输出:
Hello