Java注解

1 什么是Java注解

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。

Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。

首先,我们将学习一些Java内置注解,然后继续创建和使用自定义注解。

2 Java内置注解

Java中有几个内置注解。分为普通注解和元数据(用在注解上面的注解):

普通注解:

  • @Override
  • @SuppressWarnings
  • @Deprecated

元数据:

  • @Target
  • @Retention
  • @Inherited
  • @Documented

2.1 @Override

@Override注解可确保子类方法覆盖父类方法。如果没有覆盖成功,则会发生编译错误。

有时,我们会犯一些愚蠢的错误,例如拼写错误等。因此,最好标记@Override注解,以确保方法成功被覆盖。

package com.yiidian;

/**
 * 一点教程网: http://www.yiidian.com
 */
/**
 * @Override注解的例子
 */
class Animal{
    void eatSomething(){
        System.out.println("eating something");
    }
}

class Dog extends Animal{
    @Override  // 这里会编译错误,因为方法名称错误,没有方法覆盖
    void eatsomething(){
        System.out.println("eating foods");
    }
}

class Demo{
    public static void main(String args[]){
        Animal a=new Dog();
        a.eatSomething();
    }
}

以上代码会编译错误

2.2 @SuppressWarnings

@SuppressWarnings注解:用于禁止编译器发出的警告。

package com.yiidian;

/**
 * 一点教程网: http://www.yiidian.com
 */
/**
 * @SuppressWarnings注解的例子
 */
import java.util.*;

class Demo{

    @SuppressWarnings("unchecked")
    public static void main(String args[]){

        ArrayList list=new ArrayList();
        list.add("eric");
        list.add("jack");
        list.add("rose");

        for(Object obj:list)
            System.out.println(obj);

    }
}

输出结果为:

eric
jack
rose

如果删除 @SuppressWarnings("unchecked") 注解,由于我们使用的是非通用集合,它将在编译时显示警告。

2.3 @Deprecated

@Deprecated注解表示此方法已弃用,因此编译器将显示警告。该注解会告诉用户它可能在将来的版本中删除。因此,最好不要使用此类方法。

package com.yiidian;

/**
 * 一点教程网: http://www.yiidian.com
 */
/**
 * @Deprecated注解的例子
 */
class A{
    void m(){
        System.out.println("hello m");
    }

    @Deprecated
    void n(){
        System.out.println("hello n");
    }
}

class Demo{
    public static void main(String args[]){

        A a=new A();
        a.n();
    }
}

编译时输出结果为:

注意:Demo.java使用或覆盖不推荐使用的API。

注意:有关详细信息,请使用-Xlint:deprecation重新编译。

3 Java自定义注解

Java自定义注解就是开发者自己设计(定义)的注解。使用@interface来声明注解。例如:

@interface MyAnnotation {}  
  • MyAnnotation是自定义注解名称。

Java自定义注释的一些注意事项:

  • 方法不应包含任何throws
  • 方法应该返回以下值一之:基本数据类型,字符串,类,这些数据类型的枚举或数组。
  • 方法不应具有任何参数。
  • 我们应该在interface关键字之前附加@来定义注解。
  • 可以为该方法分配默认值。

4 注解的类型

Java中有三种类型的注解。

  • 标记注释
  • 单值注释
  • 多值注释

4.1 标记注解

没有方法的注解称为标记注解。例如:

@interface  MyAnnotation {} 

 @Override和@Deprecated是标记注解。

4.2 单值注解

具有一个方法的注解称为单值注解。例如:

@interface MyAnnotation {  
  int  value(); 
} 

 我们也可以提供默认值。例如:

@interface MyAnnotation {  
  int value() default 0;
} 

如何应用单值注释

让我们看一下应用单值注释的代码。

@MyAnnotation(value=10)

value可以是任何值。

4.3 多值注解

具有多个方法的注解称为多值注解。例如:

@interface MyAnnotation{  
  int value1();  
  String value2();  
  String value3();  
}  
}  

我们也可以提供默认值。例如:

@interface MyAnnotation{  
   int value1() default 1;  
   String value2() default "";  
   String value3() default "xyz";  
}  

如何应用多值注释

让我们看一下应用多值注释的代码。

@MyAnnotation(value1=10,value2="eric",value3="jack")  

5 Java元数据

  • @Target
  • @Retention
  • @Inherited
  • @Documented

5.1 @Target

@Target注解用于注解使用的位置。

java.lang.annotation.ElementType 声明了许多常量来指定注解应用的类型(使用的位置),例如TYPE,METHOD,FIELD等。让我们来看一下ElementType枚举的常量:

Element Types 使用的位置
TYPE 类,接口或枚举
FIELD 字段(属性)
METHOD 普通方法
CONSTRUCTOR 构造方法
LOCAL_VARIABLE 局部变量
ANNOTATION_TYPE 注解
PARAMETER 参数

定义类上使用注解的例子

@Target(ElementType.TYPE)  
@interface MyAnnotation{  
  int value1();  
  String value2();  
}  

定义类、方法或属性上使用注解的例子

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})  
@interface MyAnnotation{  
  int value1();  
  String value2();  
}  

5.2 @Retention

@Retention注解用于指定注解级别(作用范围)。

RetentionPolicy 作用范围
RetentionPolicy.SOURCE 指的是在编译过程中丢弃的源代码。在编译的class中将不可用。
RetentionPolicy.CLASS 引用.class文件,该文件可用于Java编译器,但不适用于JVM。注解包含在.class文件中。
RetentionPolicy.RUNTIME 是指可用于Java编译器和JVM的运行时。

@Retention的例子:

@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.TYPE)  
@interface MyAnnotation{  
  int value1();  
  String value2();  
}  

5.3 @Inherited

默认情况下,注解不被继承到子类。@Inherited注解将注解标记继承到子类。

@Inherited  
@interface ForEveryone { }//现在注解可以用于子类了
  
@interface ForEveryone { }  
class Superclass{}  
  
class Subclass extends Superclass{}  

5.4  @Documented

@Documented注解要包含在文档注释中。

6 Java自定义注解的综合案例

让我们看一下创建,应用和访问注解的简单示例。

package com.yiidian;

/**
 * 一点教程网: http://www.yiidian.com
 */
/**
 * Java自定义注解的综合案例
 */
//创建注解
import java.lang.annotation.*;
import java.lang.reflect.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MyAnnotation{
    int value();
}

//使用注解
class Hello{
    @MyAnnotation(value=10)
    public void sayHello(){System.out.println("hello annotation");}
}

//访问注解
class Demo{
    public static void main(String args[])throws Exception{

        Hello h=new Hello();
        Method m=h.getClass().getMethod("sayHello");

        MyAnnotation manno=m.getAnnotation(MyAnnotation.class);
        System.out.println("value is: "+manno.value());
    }
}

输出结果为:

value is: 10

 

推荐好课