java-注解-自定义注解-注解解析
注解
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-注解-自定义注解-注解解析相关推荐
- java注解,通过反射解析注解,模仿hibernate,获取sql语句。
常用注解: 自定义注解,标准格式: 1,target:注解作用域 2,Retention:声明周期 运行子类继承,但是子类继承只能作用到类注解,字段注解,是继承不了的. 使用注解:通过下面这种方式,为 ...
- [转] Java @interface 自定义注解
[From] http://blog.csdn.net/afterlife_qiye/article/details/53748973 1. 注解的好处 注解可以替代配置文件完成对某些功能的描述,减少 ...
- java 多重注解_Java注解-元数据、注解分类、内置注解和自定义注解
大家好,我是乐字节的小乐,上次说过了Java多态的6大特性|乐字节,接下来我们来看看Java编程里的注解. Java注解有以下几个知识点:元数据 注解的分类 内置注解 自定义注解 注解处理器 Serv ...
- java注解 自定义策略传参_Java注解教程及自定义注解
Java注解提供了关于代码的一些信息,但并不直接作用于它所注解的代码内容.在这个教程当中,我们将学习Java的注解,如何定制注解,注解的使用以及如何通过反射解析注解. Java1.5引入了注解,当前许 ...
- Java Annotation自定义注解详解
在开发过程中总能用到注解,但是从来没有自己定义过注解.最近赋闲在家,研究整理了一番,力求知其然知其所以然. 本文会尝试描述什么是注解,以及通过一个Demo来说明如何在程序中自定义注解.Demo没有实际 ...
- java之自定义注解的完整使用
小坏java自定义注解的完整使用 一.何为java注解之道 1.java 注解的理解之道 2.java 注解的使用示例之道 3.Java 如何自定义注解之道 4.java 元注解之道 5.java 如 ...
- 注解和反射详细笔记。自定义注解,元注解,内置注解。反射机制,Java Reflection,Java内存分析,反射操作注解,java.lang.reflect.Method,Class
文章目录 注解 什么是注解 内置注解 元注解 自定义注解 反射机制 静态语言 vs 静态语言 Java Reflection 反射相关的主要API Class类 Java内存分析 创建运行时类的对象 ...
- Java通过自定义注解执行方法_Java自定义注解(使用篇)
TL;DR Java 注解广泛运用在开发之中,用于增强变量/方法/类等. 尝试说明 Java 自定义注解的使用,以及通过开源项目中的使用进行说明. 本文主要记录个人的理解,全文基于Java SE8. ...
- Java中自定义注解的使用
Java中自定义注解的使用 一般来说,市面上有一些的框架,企业都不会直接拿过来就用,通过会做二次开发或封装,为了更加适配自己的开发规范和业务.那么在封装或适配的过程中,自定义注解就起着比较重要的作用. ...
- java 获取自定义参数类型_Springboot中使用自定义参数注解获取 token 中用户数据...
使用自定义参数注解获取 token 中User数据 使用背景 在springboot项目开发中需要从token中获取用户信息时通常的方式要经历几个步骤 拦截器中截获token TokenUtil工具类 ...
最新文章
- mysql 字段存放小图标_让MySQL支持emoji图标存储
- sql 两个表字段不一样合并查询_数据分析进阶--SQL多表查询
- python源程序执行的方式是什么执行-python调用可执行文件的方法
- python算术运算_Python 的二元算术运算详解
- 学习Linux系统的态度及技巧
- php找不到gearmanClent类,centos 使用docker搭建Gearman任务分发系统 ,Gearman的安装和使用...
- Redux Vuex
- git 创建本地仓库、远程仓库,上传项目
- qtreewidget 获取根节点_详解去中心化信任根dRoT技术
- js+获取当前域名及跳转、下载操作
- Android文本框实现搜索和清空效果
- #3120. 「CTS2019 | CTSC2019」珍珠
- 一辆车,一年大概要花费多少钱,除了油费?
- powershell自动化操作AD域、Exchange邮箱系列(2)—环境要求、搭建及初步演示
- 【实物】端到端自动驾驶搭建教程(三)附完整资料
- SQLServer 之 2008还原的时候无法获得对数据库的独占访问权解决
- 计算机网络无线局域网设计,无线校园网设计全攻略
- 织梦采集工具-织梦CMS采集教程
- C++查詢wry.dat中的IP地址信息
- 中国这10家慕课网站,您需要知道