通过自定义JAVA注解来理解JAVA注解
来源:互联网 发布:淘宝如何宝贝上架。 编辑:程序博客网 时间:2024/06/01 09:54
什么是JAVA注解?这是百度百科的解释:
定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
作用分类:
①编写文档:通过代码里标识的元数据生成文档【生成文档doc文档】
②代码分析:通过代码里标识的元数据对代码进行分析【使用反射】
③编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】
①和 ③比较容易理解。重点说说②。写过JAVA代码的人对注解都不陌生,尤其在各种框架中很常见。这些注解都非常优秀,也很容易理解,但是,为什么要使用注解?注解是如何工作的?让我自定义一个注解来解释,相信理解了这个示例以后,对注解的认识就不会模糊了。
首先我们分析一个场景,我们有一个叫Person的POJO类,代码如下:
public class Person { private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; }}
然后有这样一个HashMap:
private static Map input = new HashMap();static{ input.put("name", "Boaz"); input.put("age", "29");}
需求是把这个HashMap的值转换为Person这个pojo类,map中的key值和Person类中的属性名是相同的,我们使用反射的方式来实现,完整代码如下:
public class Main { private static Map input = new HashMap(); static{ input.put("name", "Boaz"); input.put("age", "29"); } public static void main(String[] args) { Person person = Map2Pojo(input, Person.class); System.out.print(person); } private static <T> T Map2Pojo(Map input, Class<T> clazz) { Method[] methods = clazz.getMethods(); T t; try{ t = clazz.newInstance(); }catch(Exception e) { e.printStackTrace(); return null; } for(Method method : methods) { input.keySet().forEach((key) -> { if(("set" + key).equals(method.getName().toLowerCase())) { try{ method.invoke(t, input.get(key)); }catch(Exception e) { e.printStackTrace(); return; } } }); } return t; }}
现在这个Map2Pojo工具类已经可以工作了,但是现在来了一个新Map:
private static Map input = new HashMap();static { input.put("Name", "Boaz"); input.put("Age", "29");}
跟之前的Map没有什么不同,只是key值的首字母大写了,显然,上面的Map2Pojo工具类这个时候就不能工作了。Map2Pojo是一个通用类,可以为很多Pojo转换服务,在这个类里为这个情况添加if-else来单位为Person这个变化来处理是不合适的。
这个时候就是注解登场了,我们在Person类中增加如下自定义注解:
public class Person { private String name; private String age; public String getName() { return name; } @MapKey(KeyName = "Name") public void setName(String name) { this.name = name; } public String getAge() { return age; } @MapKey(KeyName = "Age") public void setAge(String age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; }}
跟最开始的Person类相比,在Set方法上增加了注解@MapKey,这是一个自定义注解,该注解源码如下:
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MapKey { String KeyName() default "";}
定义注解的关键字是@interface,该注解上还有@Target(ElementType.METHOD)和@Retention(RetentionPolicy.RUNTIME)两个注解,这两个注解被称为”修饰注解的注解”,从字面是就可以理解,@Target(ElementType.METHOD)表示说明该注解只能注解方法,@Retention(RetentionPolicy.RUNTIME)表示该注解在运行时有效。
在注解体中,格式就类似于Key-Value格式,KeyName相当于就是键,值则可以在使用注解的时候获取,像Person类中的@MapKey(KeyName= “Name”),这里也赋予了一个默认值为空字符串。
注解定义和使用后,我们对Map2Pojo工具类稍作修改,修改后完整源码如下:
public class Main { private static Map<String, String> input = new HashMap<String, String>(); static { input.put("Name", "Boaz"); input.put("Age", "29"); } public static void main(String[] args) { Person person = Map2Pojo(input, Person.class); System.out.print(person); } private static <T> T Map2Pojo(Map input, Class<T> clazz) { Method[] methods = clazz.getMethods(); T t; try { t = clazz.newInstance(); } catch (Exception e) { e.printStackTrace(); return null; } for (Method method : methods) { input.keySet().forEach((key) -> { if (method.getAnnotations().length == 1) { MapKey mapKey = (MapKey) method.getAnnotations()[0]; String realKey = mapKey.KeyName(); if (key.equals(realKey)) { try { method.invoke(t, input.get(key)); } catch (Exception e) { e.printStackTrace(); return; } } } if (("set" + key).equals(method.getName().toLowerCase())) { try { method.invoke(t, input.get(key)); } catch (Exception e) { e.printStackTrace(); return; } } }); } return t; }}
修改的部分在21-33行,这里就读取了每个Method的注解MapKey,然后获取注解MapKey中的KeyName值来同Map中的key值进行映射。
这个示例中的注解为运行时注解,大多数自定义注解都是运行时注解。从我的角度来理解,注解可以算做是一种增加重用的机制,在这个示例中,新增了一个注解,Person类就可以在改变注解值的情况下适配不同的Map的Key值!
- 通过自定义JAVA注解来理解JAVA注解
- 如何理解java自定义注解
- Java注解-自定义注解
- Java注解----自定义注解
- Java注解自定义注解
- 【Java】【注解】自定义注解
- java 自定义注解annotation和通过反射获取注解
- Java通过反射获取自定义注解
- java之注解 自定义注解
- Java注解-自定义注解实例
- Java注解二 自定义注解
- Java注解及自定义注解
- java 注解详解,自定义注解
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 引用类型的比较
- python中super用法研究
- leetcode Maximum Gap
- java中正则表达式使用
- php中的trait
- 通过自定义JAVA注解来理解JAVA注解
- linux命令系列三之解压-压缩
- Java集合小结
- Android绘图
- Java_IO_BufferedIntputStream_And_BufferedOutputStream
- 抽象工厂模式--简单的看法和使用
- 【ITOO】MVC之Razor
- HTTP TCP UDP
- 国内从事计算机视觉领域的公司