java注解
概述:
java1.5加入了注解的概念,什么是注解?注解有什么好处?
注解:java提供的一种源程序关联任何信息和任何元数据的途径和方法。
注解使代码变得简洁,例如spring中引入了大量的注解。
1.JDK中的注解
@override 标识重写
@Deprecated 标识过时
@SuppressWarnings() 忽略警告 一般IDE要警告可以自动帮我们生成
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) //忽略警告的类型 @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { String[] value(); }
2.第三方注解
例如spring,mybatis中的一些注解
3.注解的类型
1.源码注解 只在源码显示,编译时会丢失
2.编译注解 编译时候会记录到class中,运行时忽略。例如JDK的三个注解
3.运行注解 运行时候存在可以通过反射读取
4.自定义注解
1.元注解
元注解 | 描述 |
@Target |
表示该注解可以用于什么地方。可能的ElementType参数包括: CONSTRUCTOR:构造器的生命 FIELD:域声明(包括enum实例) LOCAL_VARIABLE:局部变量声明 METHOD:方法声明 PACKAGE:包声明 PARAMETER:参数声明 TYPE:类、接口(包括注解类型)和enum声明 ANNOTATION_TYPE:注解声明(与TYPE的区别?,专门用在注解上的TYPE) TYPE_PARAMETER:Java8 TYPE_USE:Java8 |
@Retention |
表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括: SOURCE:注解将在编译器丢弃 CLASS:注解在class文件中可用,但会被VM丢弃 RUNTIME:VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息 |
@Documented | 标识型注解:生成javadoc的时候会包含注解信息 |
@Inherited | 标识型注解:允许子类继承父类中的注解(用在子类与父类之间,接口和实现类之间无效) |
java8新增元注解@Repeatable
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Repeatable { /** * Indicates the <em>containing annotation type</em> for the * repeatable annotation type. * @return the containing annotation type */ Class<? extends Annotation> value(); }
注意java8新增(可重复注解和类型注解)详情请查看博主的java8新特性
2.自定义注解的语法要求
1 package simple; 2 import java.lang.annotation.*; 3 /** 4 * @ClassName MyAnno 5 * @Description 6 * @Author 刘志红 7 * @Date 2019/3/28 8 **/ 9 //下面四个为元注解 10 @Target({ElementType.METHOD,ElementType.FIELD})//注解的作用域 11 @Retention(RetentionPolicy.RUNTIME) //定义注解的类型 12 @Inherited //标识该注解可以被继承 13 @Documented //将注解包含在javadoc中 14 public @interface /*前面整体为定义注解的关键字*/ MyAnno { 15 //注解成员以无参无异常的方式声明 用default指定默认值 16 //成员的类型是受限制的,合法的类型包含原始类型(基本数据类型)、String、Class、Annotation、Enumeration 17 //注意如果注解成员只有一个的时候,我们应该使用成员名value(这是一个规范,用别的也不报错),使用的时候可以省略成员名和= 直接写值即可。 18 String desc(); 19 String author(); 20 int age() default 20; 21 }
3.自定义注解的使用实例:通过反射获取注解信息动态的控制程序运行逻辑
简单的一个给字段用注解赋值:
package simple; import java.lang.annotation.*; /** * @ClassName MyAnno * @Description 自定义注解用于给字段自动复制 * @Author 刘志红 * @Date 2019/3/28 **/ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnno { String value() default "xiaoqiang"; }
package simple; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @ClassName Handler * @Description 反射解析类中注解 * @Author 刘志红 * @Date 2019/3/28 **/ public class Handler { public void hand(Object o) { try { Class<?> pojo = o.getClass(); Field[] fields = pojo.getDeclaredFields(); for (Field f : fields) { boolean annotationPresent = f.isAnnotationPresent(MyAnno.class); if (annotationPresent) { MyAnno annotation = f.getAnnotation(MyAnno.class); String value = annotation.value(); String name = f.getName(); //处理名字首字母大写可以方便构造set方法 String setName="set"+name.substring(0, 1).toUpperCase()+name.substring(1); Method method = pojo.getMethod(setName, String.class); method.invoke(o, value); } } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }
package simple; /** * @ClassName Pojo * @Description 使用注解的类 * @Author 刘志红 * @Date 2019/3/28 **/ public class Pojo { @MyAnno("旺财") private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
package simple; /** * @ClassName Test * @Description * @Author 刘志红 * @Date 2019/3/26 **/ public class Test { public static void main(String[] args) { Pojo pojo=new Pojo(); Handler handler = new Handler(); handler.hand(pojo); System.out.println(pojo.getName()); } }
后面会补一个简单用注解实现数据库实体类映射的例子,请继续关注。
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!