zoukankan      html  css  js  c++  java
  • [Java开发之路](15)注解

    1. 简单介绍

    注解(也被称为元数据),为我们在代码中加入信息提供了一种形式化的方法。

    注解在一定程度上是把元数据与源码文件结合在一起,而不是保存在外部文档中这一大趋势之下所催生的。


    它能够提供用来完整的描写叙述程序所需的信息。而这些信息是无法使用Java来表达的。

    因此。注解使得我们能够以将编译器来測试和验证的格式。存储有关程序的额外信息。注解能够用来生成描写叙述符文件。甚至是新的类定义。

    通过使用注解。我们能够将这些元数据保存在Java源码中,并利用Annotation API为自己的注解构造处理工具


    注解能够生成更加干净易读的代码以及编译器类型检查等等。

    注解(annotation)实在实际的源码级别保存全部的信息,而不是某种凝视性文字(comment),这使得代码更加简洁。便于维护。

    2. 注解分类

    依照执行机制分类 描写叙述
    源代码注解 注解仅仅在源代码中存在,编译成.class文件就不存在了
    编译时注解 注解仅仅在源代码和.class文件里都存在(比如:@override)
    执行时注解 在执行阶段还起作用,甚至影响执行逻辑的注解(比如:@Autowired)


    3. 内置注解:

    (1)@override

    表示当前的方法定义将覆盖超类中的方法。假设你不小心拼写错误,或者方法签名对不上被覆盖的方法。编译器就会发出错误提示。


    (2)@Deprecated

    假设程序猿使用了注解为它的元素。那么编译器会发出警告信息。

    (3)@SuppressWarnings

    关闭不当的编译器警告信息(在java SE5 之前。也能够使用这个注解,只是被忽略不起作用)

    4. 基本的语法

    4.1 定义注解

    能够看到注解的定义非常像接口的定义。

    其实,与其它不论什么Java接口一样,注解也会被编译成class文件。

    package com.qunar.annotation;
     
    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;
     
    public class Annotation {
    // 定义Description注解
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    // 使用@interface keyword定义注解
    public @interface Description{
    // 成员以无參无异常方式声明
    String desc();
    String author();
    // 能够使用defaultkeyword为成员指定一个默认值
    int age() default 18;
    }
    }

    除了@符号以外,@Description的定义非常像一个接口。

    定义注解的时候会须要一些元注解。如@Target和@Retention。@Target用来定义你的注解将用于什么地方(是一个方法上还是一个类上),@Retention用来定义该注解在哪一个级别上可用(在源码上或者是类文件上或者是执行时)。详细以下解说。


    4.2 注解元素

    注解@Description中包括int元素age,以及String元素desc和author。注解元素能够使用的类型例如以下:
    • 全部基本数据类型(int,float。boolean等)
    • String
    • Class
    • enum
    • Annotation
    • 以上类型的数组
    假设你使用了其它类型。那么编译器就会报错。

    注意,也不同意使用不论什么包装类型。只是因为自己主动打包的存在,这算不上什么限制。注解也能够作为元素的类型。也就是注解能够嵌套。


    4.3 默认值限制

    编译器对元素的默认值有些过分的挑剔。

    首先。元素不能有不确定的值。也就是说元素必需要么有默认值,要么使用注解时提供元素的值。
    其次。对于非基本类型的元素,不管是在源码中声明时,或者是在注解接口中定义默认值时,都不能以null作为其值。为了这个约束,我们仅仅能自定义一些特殊的值,比如空字符串或者负数,来表示某个元素不存在。

    4.4 元注解

    元注解仅仅负责注解其它的注解。

    元注解 參数 描写叙述



    @Taget


    CONSTRUCTOR 构造器的声明

               表示注解能够用于什么地方


    FIELD 域声明
    METHOD 方法声明
    PACKAGE 包声明
    PARAMETER 參数声明
    TYPE 类,接口或enum声明
    LOCAL_VARIABLE 局部变量声明  

    @Retention
    SOURCE 注解仅仅在源代码中存在。编译成.class文件就不存在了
            表示须要在什么级别保存该注解信息
    CLASS 注解仅仅会在.class文件存在,会被VM丢弃
    RUNTIME VM将在执行期也保留注解。因此能够通过反射机制读取注解的信息
    @Document     将此注解包括在Javadoc中
    @Inherited     同意子类继承父类中的注解


    4.5 使用注解

    语法:@<注解名称>(<成员名1> = <成员值1>。<成员名2> = <成员值2>。...)

    package com.qunar.annotation;
     
    import com.qunar.annotation.Annotation.Description;
     
    public class Student {
    private String name;
    @Description(desc = "set name for student object" , author = "sjf0115")
    public String getName() {
    return name;
    }
    @Description(desc = "get name from student object" , author = "sjf0115", time = "2016-01-11")
    public void setName(String name) {
    this.name = name;
    }
    }


    5. 解析注解

    通过反射机制获取类。函数或者成员上的执行时注解信息,从而实现动态控制程序执行的逻辑。

    package com.qunar.annotation;
     
    import java.lang.reflect.Method;
     
    import com.qunar.annotation.Annotation.Description;
     
    public class ParseAnnotation {
    public static void main(String[] args){
    Class<?

    > class1 = null;

    try {
    // 使用类载入器载入类
    class1 = Class.forName("com.qunar.annotation.Student");
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
    // 推断Student类上是否有Description注解
    boolean isExits = class1.isAnnotationPresent(Description.class);
    if(isExits){
    // 注解实例
    Description desc = class1.getAnnotation(Description.class);
    System.out.println("注解:" + desc.toString());
    }//if
    // 获取Student类上的全部方法
    Method[] methods = class1.getMethods();
    // 遍历全部方法
    for (Method method : methods) {
    // 推断方法上是否有Description注解
    isExits = method.isAnnotationPresent(Description.class);
    if(isExits){
    Description description = method.getAnnotation(Description.class);
    System.out.println("方法注解:" + description.toString());
    }//if
    }//for
    }
    }
    执行结果:

    方法注解:@com.qunar.annotation.Annotation$Description(time=2016-01-12, desc=set name for student object, author=sjf0115)
    方法注解:@com.qunar.annotation.Annotation$Description(time=2016-01-11, desc=get name from student object, author=sjf0115)

    package com.qunar.annotation;
     
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
     
    import com.qunar.annotation.Annotation.Description;
     
    public class ParseAnnotation {
    public static void main(String[] args){
    Class<?> class1 = null;
    try {
    // 使用类载入器载入类
    class1 = Class.forName("com.qunar.annotation.Student");
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
    // 推断Student类上是否有Description注解
    boolean isExits = class1.isAnnotationPresent(Description.class);
    if(isExits){
    // 注解实例
    Description desc = class1.getAnnotation(Description.class);
    System.out.println("注解:" + desc.toString());
    }//if
    // 获取Student类上的全部方法
    Method[] methods = class1.getMethods();
    // 遍历全部方法
    for (Method method : methods) {
    // 方法上获取全部的注解
    Annotation[] annotations = method.getAnnotations();
    for (Annotation annotation : annotations) {
    if(annotation instanceof Description){
    System.out.println("Description注解:" + annotation.toString());
    }//if
    }//for
    }//for
    }
    }

    这两个程序都用到了反射的方法:getMethods()和getAnnotation()。它们都属于AnnotatedElement接口(Class,Method与Field等类都实现了该接口)。getAnnotation()方法返回指定类型的注解对象,在这里就是Description。假设被注解的方法上没有该类型的注解,则返回null值。


















  • 相关阅读:
    BZOJ 1103 Poi2007 大都市meg
    BZOJ 2815 ZJOI2012 灾难
    【bzoj】1046: [HAOI2007]上升序列
    P1168跳房子(焫鷄如我)
    HAIO2017[打酱油的旅行!?]
    [haoi2013]花卉节
    P1298(矩阵切割)DP
    P1216 (list加强版)
    p1219最佳贸易(两边bfs写的)
    p1150[noip2013普及]表达式求值
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7199483.html
Copyright © 2011-2022 走看看