注解

1.注解概述

  • 注解是JDK1.5的新特性。
  • 标记(注解)可以加在包,类,字段,方法,方法参数以及局部变量上。
  • 注解是给编译器或JVM看的,编译器或JVM可以根据注解来完成对应的功能。

注解的作用:

​ 1.使用javadoc生成帮助文档:里边可以包含注解**@author和@version**

​ 2.编译检查@Override @FunctionalInterface

​ 3.框架的配置(框架=代码+配置):框架的时候讲

2.自定义注解(重点)

/*自定义注解:定义一个没有属性的注解格式:public @interface 注解名{}注意:注解使用的也是.java文件,编译生成的也是.class文件注解和类和接口和枚举都同一个层次*/
public @interface MyAnnotation01 {}
/*自定义注解:定义含有属性的注解注解的属性,可以看成是抽象方法,但是有默认值定义格式:public @interface 注解名{修饰符 数据类型 属性名();修饰符 数据类型 属性名() default 默认值;}注意:1.属性的修饰符固定使用public abstract,可以省略不写,不写默认也是;建议写出,可以增强语句的可读性2.属性的数据类型:a.基本数据类型(4类8种):byte,short,int,long,float,double,char,booleanb.引用类型:String类型,反射类型(Class),注解类型,枚举类型c.以及以上所有的类型的一维数组*/
public @interface MyAnnotation02 {//定义一个int类型的属性public abstract int a();//定一个double类型的属性,并给属性赋默认值8.8public abstract double d() default 8.8;//定义一个String数组类型的属性public abstract String[] arr();//定义反射类型的属性(了解)//public abstract Class clazz();//定义注解类型的属性(了解)//public abstract MyAnnotation01 my01();//定义枚举类型的属性(了解)//public abstract Color c() default Color.RED;
}
/*定义枚举枚举中的成员变量都是常量*/
public enum Color {/*public static final Color RED = new Color();public static final Color GREEN = new Color();*/RED,GREEN
}

3.使用自定义注解(重点)

/*使用自定义注解注解可以使用的位置:包上,类上|接口上,成员变量上,成员方法上,构造方法上,局部变量上,方法的参数上...注意:同一个位置,同名的注解只能使用一次不同的位置,同名的注解可以使用多次注解的使用格式:1.没有属性的注解,通过@注解名可以直接使用2.有属性的注解必须使用键值对的方式,给注解中的所有属性赋值之后,才能使用格式:@注解名(属性名=属性值,属性名=属性值,..属性名=属性值)a.有默认值的属性,可以不用赋值,使用默认值b.给多个属性赋值中间要使用逗号分隔开c.属性是数组类型,属性值需要使用{ }包裹起来;数组只有一个值,可以省略{ }arr = {"a","b","c"}  arr={"a"}==> arr="a"d.注解中只有一个属性,属性的名叫value,那么赋值的时候可以省略属性名,直接写属性值或者注解有其他属性,但是必须有默认值value=10==> 10*/
@MyAnnotation01
@MyAnnotation02(a=10,d=1.1,arr={"a","b","c"})
public class UseMyAnnotation {@MyAnnotation01@MyAnnotation02(a = 100,arr="aa")@MyAnnotation03(aaa=10,value = 20)private String name;private int age;@MyAnnotation01@MyAnnotation03(10)public UseMyAnnotation() {}public UseMyAnnotation(String name, int age) {this.name = name;this.age = age;}@MyAnnotation01public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
//定义只有一个属性的注解,属性名叫value
//也可以有其他的属性,但是属性必须有默认值
public @interface MyAnnotation03 {public abstract int aaa() default 100;public abstract int value();
}

4.注解练习_定义和使用Book注解

/*定义一个注解:Book- 包含属性:String value()   书名- 包含属性:double price()  价格,默认值为 100- 包含属性:String[] authors() 多位作者*/
public @interface Book {//书名public abstract String value();//价格,默认值为 100public abstract double price() default 100;//多位作者public abstract String[] authors();
}
/*使用自定义注解Book*/@Book(value = "钢铁是怎样炼成的",authors = "奥斯托洛夫斯基")
public class UseBook {@Book(value = "java编程思想",price = 88.8,authors = {"aaa","bbb"})public String name;
}

5.元注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*元注解:java已经定义好的注解,可以用来修饰自定义的注解1.@Target作用:用来标识注解使用的位置,如果没有使用该注解标识,则自定义的注解可以使用在任意位置。属性:ElementType[] value:只有一个属性名字叫value,使用的时候,给属性赋值直接写属性值即可java.lang.annotation.ElementType:是一个枚举,枚举中定义的变量都是常量TYPE,类,接口FIELD, 成员变量METHOD, 成员方法PARAMETER, 方法参数CONSTRUCTOR, 构造方法LOCAL_VARIABLE, 局部变量2.@Retention作用:用来标识注解的生命周期(有效范围)属性:RetentionPolicy value:只有一个属性名字叫value,使用的时候,给属性赋值直接写属性值即可java.lang.annotation.RetentionPolicy:是一个枚举,枚举中定义的变量都是常量SOURCE:注解只作用在源码阶段(.java文件中),生成的字节码文件(.class文件中)中不存在CLASS:注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值RUNTIME:注解作用在源码阶段,字节码文件阶段,运行阶段*/
@Target({ElementType.TYPE,ElementType.METHOD})//声明自定义注解可以使用在类上和方法上
@Retention(RetentionPolicy.RUNTIME)//声明自定义注解生命周期在.java文件中.class文件中和内存中都有效
public @interface Book {//书名public abstract String value();//价格,默认值为 100public abstract double price() default 100;//多位作者public abstract String[] authors();
}

6.注解解析

import com.zl.demo03Annotation.MyAnnotation01;
import org.junit.Test;import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;/*注解解析:获取注解的属性值注解解析底层使用的都是反射技术java.lang.reflect.AnnotatedElement接口:在接口中定义了注解解析相关的方法接口的实现类:实现类都重写了接口中的方法,都可以使用AccessibleObject, Class, Constructor, Field, Method, Package接口中的方法:boolean isAnnotationPresent(Class annotationClass):判断指定的对象上(Class, Constructor, Field, Method)是否有指定的注解参数:Class annotationClass:判断哪个注解,就传递哪个注解的class文件对象判断类上,方法上...有没有Book注解,就需要传递Book.class返回值:有指定的注解,返回true没有指定的注解,返回falseT getAnnotation(Class<T> annotationClass) 获取对象上(Class, Constructor, Field, Method)指定的注解参数:Class<T> annotationClass:获取哪个注解,就传递哪个注解的class文件对象获取类上,方法上...有没有Book注解,就需要传递Book.class返回值:T:返回指定的注解,获取不到返回null了解:Annotation[] getAnnotations()  获取对象上所有公共的注解Annotation[] getDeclaredAnnotations() 获取对象上所有声明的注解*/
@MyAnnotation01
@Book(value = "西游记",price = 66.6,authors = "吴承恩")
public class Demo01ParseAnnotation {@Book(value = "水浒传",authors = "施耐庵")public void method(){}/*解析类上的注解实现步骤:1.获取类的class文件对象2.使用class文件对象中的方法isAnnotationPresent判断类上是否有指定的Book注解3.如果类上有Book注解,使用class文件对象中的方法getAnnotation获取到Book注解4.使用注解名.属性名()获取注解的属性值*/@Testpublic void parseClassAnnotation() throws ClassNotFoundException {//1.获取类的class文件对象Class clazz = Class.forName("com.zl.demo05Annotation.Demo01ParseAnnotation");//2.使用class文件对象中的方法isAnnotationPresent判断类上是否有指定的Book注解boolean b = clazz.isAnnotationPresent(Book.class);System.out.println(b);//3.如果类上有Book注解,使用class文件对象中的方法getAnnotation获取到Book注解if(b){Book book = (Book)clazz.getAnnotation(Book.class);//4.使用注解名.属性名()获取注解的属性值String value = book.value();System.out.println(value);double price = book.price();System.out.println(price);String[] authors = book.authors();System.out.println(Arrays.toString(authors));}}/*解析方法上的注解实现步骤:1.获取类的class文件对象2.使用class文件对象中的方法getMethods获取类中所有的公共成员方法,返回一个Method数组3.遍历Method数组,获取每一个Method对象4.使用Method对象中的方法isAnnotationPresent判断方法上是否有Book注解5.如果方法上有Book注解,使用Method对象中的方法getAnnotation获取Book注解6.使用注解名.属性名()获取属性的值*/@Testpublic void parseMethodAnnotation(){//1.获取类的class文件对象Class clazz = Demo01ParseAnnotation.class;//2.使用class文件对象中的方法getDeclaredMethods获取类中所有的成员方法,返回一个Method数组Method[] methods = clazz.getDeclaredMethods();//3.遍历Method数组,获取每一个Method对象for (Method method : methods) {//4.使用Method对象中的方法isAnnotationPresent判断方法上是否有Book注解boolean b = method.isAnnotationPresent(Book.class);//System.out.println(method.getName()+"-->"+b);if(b){//5.如果方法上有Book注解,使用Method对象中的方法getAnnotation获取Book注解Book book = method.getAnnotation(Book.class);//6.使用注解名.属性名()获取属性的值System.out.println(book.value());System.out.println(book.price());System.out.println(Arrays.toString(book.authors()));}}}
}

7.注解和反射的综合演示

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;//1.自定义一个注解叫MyTest,使用元注解修饰MyTest注解(只能在方法上使用,运行期有效)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {}
//2.定义一个测试类,在测试类中定义多个方法,让部分方法使用MyTest注解
public class DemoMyTest {public void show01(){System.out.println("show01方法");}@MyTestpublic void show02(){System.out.println("show02方法");}@MyTestpublic void show03(){System.out.println("show03方法");}public void show04(){System.out.println("show04方法");}@MyTestpublic void show05(){System.out.println("show05方法");}
}
import java.lang.reflect.Method;/*注解和反射的综合案例需求:模拟Junit测试的@Test添加了@Test注解的方法,可以运行没有添加@Test注解的方法,不可以运行分析:1.自定义一个注解叫MyTest,使用元注解修饰MyTest注解(只能在方法上使用,运行期有效)2.定义一个测试类,在测试类中定义多个方法,让部分方法使用MyTest注解3.获取测试类的class文件对象4.使用class文件对象中的方法newInstance实例化对象5.使用class文件对象中的方法getMethods获取测试类中所有的成员方法,返回一个Method数组6.遍历Method数组,获取每一个Method对象7.使用Method对象中的方法isAnnotationPresent判断,Method上是否有指定的MyTest注解8.如果Method对象上有MyTest注解,使用invoke方法,运行Method*/
public class Demo01AnnotationTest {public static void main(String[] args) throws Exception {//3.获取测试类的class文件对象Class clazz = Class.forName("com.zl.demo06AnnotationTest.DemoMyTest");//4.使用class文件对象中的方法newInstance实例化对象Object obj = clazz.newInstance();//5.使用class文件对象中的方法getMethods获取测试类中所有的成员方法,返回一个Method数组Method[] methods = clazz.getDeclaredMethods();//6.遍历Method数组,获取每一个Method对象for (Method method : methods) {//7.使用Method对象中的方法isAnnotationPresent判断,Method上是否有指定的MyTest注解if(method.isAnnotationPresent(MyTest.class)){//8.如果Method对象上有MyTest注解,使用invoke方法,运行Methodmethod.invoke(obj);}}}
}

java-注解-自定义注解-注解解析相关推荐

  1. java注解,通过反射解析注解,模仿hibernate,获取sql语句。

    常用注解: 自定义注解,标准格式: 1,target:注解作用域 2,Retention:声明周期 运行子类继承,但是子类继承只能作用到类注解,字段注解,是继承不了的. 使用注解:通过下面这种方式,为 ...

  2. [转] Java @interface 自定义注解

    [From] http://blog.csdn.net/afterlife_qiye/article/details/53748973 1. 注解的好处 注解可以替代配置文件完成对某些功能的描述,减少 ...

  3. java 多重注解_Java注解-元数据、注解分类、内置注解和自定义注解

    大家好,我是乐字节的小乐,上次说过了Java多态的6大特性|乐字节,接下来我们来看看Java编程里的注解. Java注解有以下几个知识点:元数据 注解的分类 内置注解 自定义注解 注解处理器 Serv ...

  4. java注解 自定义策略传参_Java注解教程及自定义注解

    Java注解提供了关于代码的一些信息,但并不直接作用于它所注解的代码内容.在这个教程当中,我们将学习Java的注解,如何定制注解,注解的使用以及如何通过反射解析注解. Java1.5引入了注解,当前许 ...

  5. Java Annotation自定义注解详解

    在开发过程中总能用到注解,但是从来没有自己定义过注解.最近赋闲在家,研究整理了一番,力求知其然知其所以然. 本文会尝试描述什么是注解,以及通过一个Demo来说明如何在程序中自定义注解.Demo没有实际 ...

  6. java之自定义注解的完整使用

    小坏java自定义注解的完整使用 一.何为java注解之道 1.java 注解的理解之道 2.java 注解的使用示例之道 3.Java 如何自定义注解之道 4.java 元注解之道 5.java 如 ...

  7. 注解和反射详细笔记。自定义注解,元注解,内置注解。反射机制,Java Reflection,Java内存分析,反射操作注解,java.lang.reflect.Method,Class

    文章目录 注解 什么是注解 内置注解 元注解 自定义注解 反射机制 静态语言 vs 静态语言 Java Reflection 反射相关的主要API Class类 Java内存分析 创建运行时类的对象 ...

  8. Java通过自定义注解执行方法_Java自定义注解(使用篇)

    TL;DR Java 注解广泛运用在开发之中,用于增强变量/方法/类等. 尝试说明 Java 自定义注解的使用,以及通过开源项目中的使用进行说明. 本文主要记录个人的理解,全文基于Java SE8. ...

  9. Java中自定义注解的使用

    Java中自定义注解的使用 一般来说,市面上有一些的框架,企业都不会直接拿过来就用,通过会做二次开发或封装,为了更加适配自己的开发规范和业务.那么在封装或适配的过程中,自定义注解就起着比较重要的作用. ...

  10. java 获取自定义参数类型_Springboot中使用自定义参数注解获取 token 中用户数据...

    使用自定义参数注解获取 token 中User数据 使用背景 在springboot项目开发中需要从token中获取用户信息时通常的方式要经历几个步骤 拦截器中截获token TokenUtil工具类 ...

最新文章

  1. mysql 字段存放小图标_让MySQL支持emoji图标存储
  2. sql 两个表字段不一样合并查询_数据分析进阶--SQL多表查询
  3. python源程序执行的方式是什么执行-python调用可执行文件的方法
  4. python算术运算_Python 的二元算术运算详解
  5. 学习Linux系统的态度及技巧
  6. php找不到gearmanClent类,centos 使用docker搭建Gearman任务分发系统 ,Gearman的安装和使用...
  7. Redux Vuex
  8. git 创建本地仓库、远程仓库,上传项目
  9. qtreewidget 获取根节点_详解去中心化信任根dRoT技术
  10. js+获取当前域名及跳转、下载操作
  11. Android文本框实现搜索和清空效果
  12. #3120. 「CTS2019 | CTSC2019」珍珠
  13. 一辆车,一年大概要花费多少钱,除了油费?
  14. powershell自动化操作AD域、Exchange邮箱系列(2)—环境要求、搭建及初步演示
  15. 【实物】端到端自动驾驶搭建教程(三)附完整资料
  16. SQLServer 之 2008还原的时候无法获得对数据库的独占访问权解决
  17. 计算机网络无线局域网设计,无线校园网设计全攻略
  18. 织梦采集工具-织梦CMS采集教程
  19. C++查詢wry.dat中的IP地址信息
  20. 中国这10家慕课网站,您需要知道

热门文章

  1. Dart | 使用 Flutter 制作一个像 SIRI 那样的语音机器人
  2. EV https证书申请与续费
  3. 怎样设置默认浏览器,绝对干货!
  4. leetcode_1370. 上升下降字符串
  5. Pytest全栈自动化测试指南-入门
  6. 认识计算机软件的教学过程,《认识计算机》教学设计
  7. java normalize_Java Path normalize()用法及代码示例
  8. 计算机组成原理第三部: 总线与IO系统
  9. 二分图匹配-匈牙利算法, 最小路径覆盖
  10. python多线程爬取qq好友空间的留言