Java Annontation 注解的学习和理解
/**
* <html>
* <body>
* <P> Copyright 1994 JsonInternational</p>
* <p> All rights reserved.</p>
* <p> Created by Jason</p>
* </body>
* </html>
*/
package cn.ucaner.core.annotation; /**
Annontation是Java5开始引入的新特征,中文名称叫注解。
它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。
为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且供指定的工具或框架使用。
Annontation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。 Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。
注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。
包含在 java.lang.annotation 包中。 常见的用法 :
1、生成文档。这是最常见的,也是java 最早提供的注解。常用的有@param @return 等
2、跟踪代码依赖性,实现替代配置文件功能。比如Dagger 2依赖注入,未来java开发,将大量注解配置,具有很大用处;
3、在编译时进行格式检查。如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。 注解的原理:
注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。
而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象$Proxy1。
通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler的invoke方法。
该方法会从memberValues这个Map中索引出对应的值。
而memberValues的来源是Java常量池。 元注解:
@Documented –注解是否将包含在JavaDoc中
@Retention –什么时候使用该注解
@Target –注解用于什么地方
@Inherited – 是否允许子类继承该注解 1.)@Retention– 定义该注解的生命周期
● RetentionPolicy.SOURCE : 在编译阶段丢弃。
这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。
@Override, @SuppressWarnings都属于这类注解。 ● RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式 ● RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。 2.)@Target – 表示该注解用于什么地方。默认值为任何元素,表示该注解用于什么地方。可用的ElementType参数包括
● ElementType.CONSTRUCTOR:用于描述构造器
● ElementType.FIELD:成员变量、对象、属性(包括enum实例)
● ElementType.LOCAL_VARIABLE:用于描述局部变量
● ElementType.METHOD:用于描述方法
● ElementType.PACKAGE:用于描述包
● ElementType.PARAMETER:用于描述参数
● ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明 3.)@Documented–一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中。 4.)@Inherited – 定义该注释和子类的关系
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。
如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
*/
public class AnnoDefined { }
/**
* <html>
* <body>
* <P> Copyright 1994 JsonInternational</p>
* <p> All rights reserved.</p>
* <p> Created on 19941115</p>
* <p> Created by Jason</p>
* </body>
* </html>
*/
package cn.ucaner.core.annotation; public class AnnoDemo { @FieldMeta(id=true,name="序列号",order=1,description="ID")
private int id; @FieldMeta(name="姓名",order=3,description="姓名")
private String name; @FieldMeta(name="年龄",order=2)
private int age; @FieldMeta(description="描述",order=4)
public String desc(){
return "java反射获取annotation的测试";
} public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public 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;
} }
/**
* <html>
* <body>
* <P> Copyright 1994 JsonInternational</p>
* <p> All rights reserved.</p>
* <p> Created by Jason</p>
* </body>
* </html>
*/
package cn.ucaner.core.annotation; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @Package:cn.ucaner.core.annotation
* @ClassName:FieldMeta
* @Description: <p> @FieldMeta - 注解描述信息 </p>
* @Author: - Jason
* @CreatTime:2018年10月18日 下午9:53:45
* @Modify By:
* @ModifyTime: 2018年10月18日
* @Modify marker:
* @version V1.0
*/
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target({ElementType.FIELD,ElementType.METHOD})//定义注解的作用目标**作用范围字段、枚举的常量/方法
@Documented//说明该注解将被包含在javadoc中
public @interface FieldMeta { /**
* 是否为序列号
* @return
*/
boolean id() default false; /**
* 字段名称
* @return
*/
String name() default "default_name"; /**
* 是否可编辑
* @return
*/
boolean editable() default true; /**
* 是否在列表中显示
* @return
*/
boolean summary() default true; /**
* 字段描述
* @return
*/
String description() default ""; /**
* 排序字段
* @return
*/
int order() default 0; }
/**
* <html>
* <body>
* <P> Copyright 1994 JsonInternational</p>
* <p> All rights reserved.</p>
* <p> Created on 19941115</p>
* <p> Created by Jason</p>
* </body>
* </html>
*/
package cn.ucaner.core.annotation; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /*1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明*/ /*(RetentionPoicy)
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)*/ @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName { String value() default "Apple";
}
/**
* <html>
* <body>
* <P> Copyright 1994 JsonInternational</p>
* <p> All rights reserved.</p>
* <p> Created by Jason</p>
* </body>
* </html>
*/
package cn.ucaner.core.annotation; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; /**
* @Package:cn.ucaner.core.annotation
* @ClassName:Parent
* @Description: <p> Parent<T> </p>
* @Author: - Jason
* @CreatTime:2018年10月18日 下午9:54:26
* @Modify By:
* @ModifyTime: 2018年10月18日
* @Modify marker:
* @version V1.0
*/
public class Parent<T> { private Class<T> entity; public Parent() {
init();
} public List<SortableField> init(){
List<SortableField> list = new ArrayList<SortableField>();
/**getClass().getGenericSuperclass()返回表示此 Class 所表示的实体(类、接口、基本类型或 void)
* 的直接超类的 Type(Class<T>泛型中的类型),然后将其转换ParameterizedType。。
* getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。
* [0]就是这个数组中第一个了。。
* 简而言之就是获得超类的泛型参数的实际类型。。*/
// entity = (Class<T>)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
// FieldMeta filed = entity.getAnnotation(FieldMeta.class);
this.getClass().getGenericSuperclass();
//genericSuperclass.
if(this.entity!=null){ /**返回类中所有字段,包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段
* entity.getFields();只返回对象所表示的类或接口的所有可访问公共字段
* 在class中getDeclared**()方法返回的都是所有访问权限的字段、方法等;
* 可看API
* */
Field[] fields = entity.getDeclaredFields();
//
for(Field f : fields){
//获取字段中包含fieldMeta的注解
FieldMeta meta = f.getAnnotation(FieldMeta.class);
if(meta!=null){
SortableField sf = new SortableField(meta, f);
list.add(sf);
}
} //返回对象所表示的类或接口的所有可访问公共方法
Method[] methods = entity.getMethods(); for(Method m:methods){
FieldMeta meta = m.getAnnotation(FieldMeta.class);
if(meta!=null){
SortableField sf = new SortableField(meta,m.getName(),m.getReturnType());
list.add(sf);
}
}
//这种方法是新建FieldSortCom类实现Comparator接口,来重写compare方法实现排序
// Collections.sort(list, new FieldSortCom());
Collections.sort(list, new Comparator<SortableField>() {
@Override
public int compare(SortableField s1,SortableField s2) {
return s1.getMeta().order()-s2.getMeta().order();
// return s1.getName().compareTo(s2.getName());//也可以用compare来比较
} });
}
return list; } }
/**
* <html>
* <body>
* <P> Copyright 1994 JsonInternational</p>
* <p> All rights reserved.</p>
* <p> Created on 19941115</p>
* <p> Created by Jason</p>
* </body>
* </html>
*/
package cn.ucaner.core.annotation; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @Package:cn.ucaner.core.annotation
* @ClassName:SayHiAnnotation
* @Description: <p> 自定义注解,用来配置方法</p>
* @Author: - Jason
* @CreatTime:2018年4月10日 下午9:39:10
* @Modify By:
* @ModifyTime: 2018年4月10日
* @Modify marker:
* @version V1.0
*/
@Retention(RetentionPolicy.RUNTIME) // 表示注解在运行时依然存在
@Target(ElementType.METHOD) // 表示注解可以被使用于方法上
public @interface SayHiAnnotation { String paramValue() default "Jason";
// 表示我的注解需要一个参数 名为"paramValue" 默认值为"Jason"
}
/**
* <html>
* <body>
* <P> Copyright 1994 JsonInternational</p>
* <p> All rights reserved.</p>
* <p> Created on 19941115</p>
* <p> Created by Jason</p>
* </body>
* </html>
*/
package cn.ucaner.core.annotation; /**
* @Package:cn.ucaner.core.annotation
* @ClassName:SayHiEmlement
* @Description: <p> 要使用SayHiAnnotation的元素所在类 </br> 由于我们定义了只有方法才能使用我们的注解,我们就使用多个方法来进行测试</p>
* @Author: - DaoDou
* @CreatTime:2018年4月10日 下午9:39:49
* @Modify By:
* @ModifyTime: 2018年4月10日
* @Modify marker:
* @version V1.0
*/
public class SayHiEmlement { // 普通的方法
public void SayHiDefault(String name,String age){
System.out.println("Hi, " + name+age);
} // 使用注解并传入参数的方法
@SayHiAnnotation(paramValue="Jack")
public void SayHiAnnotation(String name,String age){
System.out.println("Hi, " + name+age);
} // 使用注解并使用默认参数的方法
@SayHiAnnotation
public void SayHiAnnotationDefault(String name,String age){
System.out.println("Hi, " + name + age);
}
}
/**
* <html>
* <body>
* <P> Copyright 1994 JsonInternational</p>
* <p> All rights reserved.</p>
* <p> Created by Jason</p>
* </body>
* </html>
*/
package cn.ucaner.core.annotation; import java.lang.reflect.Field; /**
* @Package:cn.ucaner.core.annotation
* @ClassName:SortableField
* @Description: <p> SortableField 可排序字段 </p>
* @Author: - Jason
* @CreatTime:2018年10月18日 下午9:55:25
* @Modify By:
* @ModifyTime: 2018年10月18日
* @Modify marker:
* @version V1.0
*/
public class SortableField { public SortableField(){} public SortableField(FieldMeta meta, Field field) {
super();
this.meta = meta;
this.field = field;
this.name=field.getName();
this.type=field.getType();
} public SortableField(FieldMeta meta, String name, Class<?> type) {
super();
this.meta = meta;
this.name = name;
this.type = type;
} private FieldMeta meta;
private Field field;
private String name;
private Class<?> type; public FieldMeta getMeta() {
return meta;
}
public void setMeta(FieldMeta meta) {
this.meta = meta;
}
public Field getField() {
return field;
}
public void setField(Field field) {
this.field = field;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} public Class<?> getType() {
return type;
} public void setType(Class<?> type) {
this.type = type;
} }
/**
* <html>
* <body>
* <P> Copyright 1994 JsonInternational</p>
* <p> All rights reserved.</p>
* <p> Created by Jason</p>
* </body>
* </html>
*/
package cn.ucaner.core.annotation; import java.lang.reflect.Field; /**
* @Package:cn.ucaner.core.annotation
* @ClassName:TestMain
* @Description: <p> TestMain </p>
* @Author: - Jason
* @CreatTime:2018年10月19日 下午3:17:20
* @Modify By:
* @ModifyTime: 2018年10月19日
* @Modify marker:
* @version V1.0
*/
public class TestMain { @FieldMeta(name="Jason")//注解的使用
private Object obj; @FieldMeta(name="Andy",description="Intersting")
private String name; @FruitName(value="Apple")
@FieldMeta
private String profile; public String getProfile() {
return profile;
} public void setProfile(String profile) {
this.profile = profile;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} public Object getObj() {
return obj;
} public void setObj(Object obj) {
this.obj = obj;
} /**
* @Description: Just for test 注解反射的方式拿到元信息数据
* @throws Exception void
*/
public static void main(String[] args) throws Exception{ Field[] fields = TestMain.class.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getName());
if(field.isAnnotationPresent(FieldMeta.class)){
FieldMeta fieldMeta = field.getAnnotation(FieldMeta.class);
String str = fieldMeta.name();
String description = fieldMeta.description();
System.out.println(str);
System.out.println(description);
}if (field.isAnnotationPresent(FruitName.class)) {
FruitName fruitName = field.getAnnotation(FruitName.class);
System.out.println(fruitName.value());
}else{
//FruitName fruitName = field.getAnnotation(FruitName.class);
//System.out.println(fruitName.value());
}
} } }
//Output
//obj
//Jason
//
//name
//Andy
//Intersting
//profile
//default_name
//
//Apple
Java Annontation 注解的学习和理解的更多相关文章
- Java Annontation(注解)详解
java中经常用到注解(Annontation),索性整理了下关于注解的相关知识点: 一.概念 Annontation是Java5开始引入的新特征,类似与.NET 中的attribute.中文名称一般 ...
- java中容器的学习与理解
以前一直对于java中容器的概念不理解,虽然学习过,但始终没有认真理解过,这几天老师提出了这样一个问题,你怎么理解java中的容器.瞬间就蒙了.于是各种搜资料学习了一下,下面是我学习后整理出来的的一些 ...
- Java 8 Lambda表达式学习和理解
Java 8 Lambda表达式和理解 说明:部分资料来源于网络 时间:20190704 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性.Lambda 允许把函数作为一 ...
- 深入理解Java:注解
注解作用:每当你创建描述符性质的类或者接口时,一旦其中包含重复性的工作,就可以考虑使用注解来简化与自动化该过程. Java提供了四种元注解,专门负责新注解的创建工作. 元注解 元注解的作用就是负责注解 ...
- [2]注解(Annotation)-- 深入理解Java:注解(Annotation)自定义注解入门
转载 http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 深入理解Java:注解(Annotation)自定义注解入门 要深入学习 ...
- 深入理解Java:注解(Annotation)自己定义注解入门
深入理解Java:注解(Annotation)自己定义注解入门 要深入学习注解.我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前.我们就必须要了解Java为我们提供的元注解和相关定义注解的 ...
- Java四种引用--《深入理解Java虚拟机》学习笔记及个人理解(四)
Java四种引用--<深入理解Java虚拟机>学习笔记及个人理解(四) 书上P65. StrongReference(强引用) 类似Object obj = new Object() 这类 ...
- [3] 注解(Annotation)-- 深入理解Java:注解(Annotation)--注解处理器
转载 http://www.cnblogs.com/peida/archive/2013/04/26/3038503.html 深入理解Java:注解(Annotation)--注解处理器 如果没有用 ...
- [1] 注解(Annotation)-- 深入理解Java:注解(Annotation)基本概念
转载 http://www.cnblogs.com/peida/archive/2013/04/23/3036035.html 深入理解Java:注解(Annotation)基本概念 什么是注解(An ...
随机推荐
- 一大波 Facebook Libra 技术文章来袭
由于 Libra 具有真正的稳定的可编程货币的特性, Libra 或许可以带来又一波平台红利. 上周我们(深入浅出区块链技术社区)发起了 Libra 技术文档的翻译计划,到这周文档已经翻译了一半.欢迎 ...
- js操作表格、table、
js添加一行.删除一行 let str="<tr>" +"<td>"+a[1]+"</td>" +&qu ...
- 关于conda和jupyter使用
conda建立虚拟环境 常用指令 conda env list # 查看环境 conda create -n env_name python=3.6.8 # 安装对应python的虚拟环境 conda ...
- [技术博客]使用PanResponder实现响应左右滑动手势
在实现用户左右滑动完成不同操作时,使用react-native的官方API--PanResponder响应用户手势操作. PanResponder介绍 PanResponder中文文档 PanResp ...
- JetBrains套装免费学生授权申请(IntelliJ, ReSharper, WebStorm...)
IntelliJ作为一款强大的Java开发IDE,售价自然也不会低.但是对于学生或教师来说,JetBrains开发工具免费提供给学生和教师使用.而且取得一次授权后只需要使用相同的 JetBrains ...
- JAVA | Java对象的内存分配过程是如何保证线程安全的?
JAVA | Java对象的内存分配过程是如何保证线程安全的? 专注于Java领域优质技术,欢迎关注 作者 l Hollis 来源 l Hollis(ID:hollischuang) JVM内存结构, ...
- mvn命令修改pom打包的版本号
在java项目中打包经常需要修改镜像的版本号.可以使用如下命令 mvn versions: // 如果要打包使用人如下命令,打印详细信息使用 -X mvn clean deploy -e -Dskip ...
- spring MVC cors跨域实现源码解析 CorsConfiguration UrlBasedCorsConfigurationSource
spring MVC cors跨域实现源码解析 spring MVC cors跨域实现源码解析 名词解释:跨域资源共享(Cross-Origin Resource Sharing) 简单说就是只要协议 ...
- pytorch 中conv1d操作
参考:https://blog.csdn.net/liujh845633242/article/details/102668515 这里我重点说一下1D卷积,2D卷积很好理解,但是1D卷积就不是那么好 ...
- SketchyGAN: Towards Diverse and Realistic Sketch to Image Synthesis - 1 - 论文学习
https://github.com/wchen342/SketchyGAN Abstract 从人体草图中合成逼真的图像是计算机图形学和视觉学中的一个具有挑战性的课题.现有的方法要么需要精确的边缘图 ...