Java注解教程和示例

8次阅读

共计 4305 个字符,预计需要花费 11 分钟才能阅读完成。

Java 注解教程和示例

塔尼亚·辛格

Java 注解使我们可以将元数据信息添加到源代码中,尽管它们不是程序本身的一部分。注解是从 JDK 5 添加到 Java 的。注解对其注解的代码的操作没有直接影响(即,它不影响程序的执行)。

在本教程中,我们将涵盖以下主题:注解的用法,如何应用注解,Java 中可用的预定义注解类型以及如何创建自定义注解。

注解的用途是什么?

1)编译器指令:Java(@Deprecated,@Override&@SuppressWarnings)提供了三个内置注解,可用于向编译器提供某些指令。例如,@override 批注用于指示编译器已批注的方法将覆盖该方法。本文的下一部分将讨论更多有关这些内置注解的示例。

2)编译时指令:注解可以向编译器提供编译时指令,软件构建工具可以将其进一步用于生成代码,XML 文件等。

3)运行时指令:我们可以定义在运行时可用的批注,我们可以使用 java 反射对其进行访问,并且可以在运行时向程序提供指令。在同一篇文章的后面,我们将借助示例进行讨论。

注解基础

注解始终以符号开头,@后跟注解名称。该符号 @向编译器指示这是一个注解。

例如,@Override
在这里 @符号表示这是一个注解,而 Override 是此注解的名称。

在哪里可以使用注解?
注解可以应用于类,接口,方法和字段。例如,以下注解将应用于该方法。

@Override void myMethod(){// 做某事}

下一节将说明此批注的确切功能,但要简要说明一下,它是指示编译器 myMethod() 重写了重写方法,该方法重写了超类的方法(myMethod())。

Java 内置注解

Java 具有三个内置注解:

@Override
@Deprecated
@SuppressWarnings

1)@Override:
在子类中重写方法时,我们应使用此批注标记该方法。这使代码易于阅读并避免了维护问题,例如:在更改父类的方法签名时,必须在子类(使用此批注的地方)中更改签名,否则编译器会抛出编译错误。当您未使用此批注时,很难跟踪。

例:

public class MyParentClass {public void justaMethod() {System.out.println("Parent class method");
    }
}


public class MyChildClass extends MyParentClass {

    @Override
    public void justaMethod() {System.out.println("Child class method");
    }
}      

我相信这个例子是不言自明的。要阅读有关此批注的更多信息,请参阅本文:@Override 内置批注。

2)@Deprecated
@Deprecated 批注指示已弃用已标记的元素(类,方法或字段),并且不应再使用。每当程序使用已被 @Deprecated 批注标记的方法,类或字段时,编译器都会生成警告。不推荐使用元素时,还应使用 Javadoc @deprecated 标记对其进行记录,如以下示例所示。使用 @Deprecated 和 @deprecated 记录大小写差异。@deprecated 用于文档目的。

例:

/**
 * @deprecated
 * reason for why it was deprecated
 */
@Deprecated
public void anyMethodHere(){// Do something}

现在,只要任何程序使用此方法,编译器都会生成警告。要阅读有关此批注的更多信息,请参阅本文:Java – @Deprecated 注解。

3)@SuppressWarnings
该注解指示编译器忽略特定的警告。例如,在下面的代码中,我正在调用不赞成使用的方法(假设方法 deprecatedMethod()已用 @Deprecated 批注标记),因此编译器应生成警告,但是我使用的是 @@ SuppressWarnings 批注,它将禁止该弃用警告。

  @SuppressWarnings("deprecation")
      void myMethod() {myObject.deprecatedMethod();
  }

创建自定义注解

注解是通过使用 @interface 创建的,后跟注解名称,如以下示例所示。
注解也可以具有元素。它们看起来像方法。例如,在下面的代码中,我们有四个元素。我们不应该为这些元素提供实现。
所有注解都扩展了 java.lang.annotation.Annotation 接口。注解不能包含任何 extends 子句。

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation{int studentAge() default 18;
    String studentName();
    String stuAddress();
    String stuStream() default "CSE";}

注意:使用注解时,可以跳过创建注解时设置了默认值的所有元素。例如,如果我将上述注解应用于一个类,则可以这样进行:

@MyCustomAnnotation(
    studentName="Chaitanya",
    stuAddress="Agra, India"
)
public class MyClass {...}

如您所见,我们没有给 studentAge 和 stuStream 元素赋予任何值,因为设置这些元素的值是可选的(注解值定义中已经设置了默认值,但是如果您想在使用注解时分配新值,则只需就像我们对其他元素所做的一样)。但是,在使用注解时,我们必须提供其他元素的值(未设置默认值的元素)。

注意:我们也可以在注解中包含数组元素。这是我们如何使用它们:
注解定义:

@interface MyCustomAnnotation {int      count();
    String[] books();
} 

用法:

@MyCustomAnnotation(
    count=3,
    books={"C++", "Java"}
)
public class MyClass {}

让我们回到正题再次:在自定义注解例子中我们使用这四个注解:@Documented,@Target,@Inherited 和 @Retention。让我们详细讨论它们。

@Documented

@Documented 注解指示使用此注解的元素应由 JavaDoc 记录。例如:

java.lang.annotation.Documented
@Documented
public @interface MyCustomAnnotation {//Annotation body}
@MyCustomAnnotation
public class MyClass {//Class body}

在为 class 生成 javadoc 时 MyClass,@MyCustomAnnotation 将包括注解。

@Target

它指定了我们可以在哪里使用注解。例如:在下面的代码中,我们将目标类型定义为 METHOD,这意味着下面的注解只能在方法上使用。

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

@Target({ElementType.METHOD})
public @interface MyCustomAnnotation {

}
public class MyClass {
   @MyCustomAnnotation
   public void myMethod()
   {//Doing something}
}

注意:1)如果未定义任何目标类型,则意味着可以将注解应用于任何元素。
2)除了 ElementType.METHOD,注解可以具有以下可能的 Target 值。

ElementType.METHOD
ElementType.PACKAGE
ElementType.PARAMETER
ElementType.TYPE
ElementType.ANNOTATION_TYPE
ElementType.CONSTRUCTOR
ElementType.LOCAL_VARIABLE
ElementType.FIELD

@Inherited 遗传

@Inherited 注解表示一个类中使用的自定义注解应由其所有子类继承。例如:

Java 的。郎。注解。遗传

java.lang.annotation.Inherited

@Inherited
public @interface MyCustomAnnotation {

}
@MyCustomAnnotation
public class MyParentClass {...}
public class MyChildClass extends MyParentClass {...}  

在这里,该类 MyParentClass 使用的 @MyCustomAnnotation 是带有 @inherited 注解的注解。这意味着子类 MyChildClass 继承了 @MyCustomAnnotation。

@Retention 保留

它指示带有注解类型的注解将保留多长时间。

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

@Retention(RetentionPolicy.RUNTIME)
@interface MyCustomAnnotation {}

在这里,我们使用了 RetentionPolicy.RUNTIME。也有两个其他选择。让我们看看它们的含义:
RetentionPolicy.RUNTIME 注解应该在运行时可用,以便通过 Java 反射进行检查。
RetentionPolicy.CLASS:注解将位于.class 文件中,但在运行时将不可用。
RetentionPolicy.SOURCE 注解将在程序的源代码中提供,而不是在.class 文件中,也不在运行时可用。

正文完
 0