/**
* <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 注解的学习和理解的更多相关文章

  1. Java Annontation(注解)详解

    java中经常用到注解(Annontation),索性整理了下关于注解的相关知识点: 一.概念 Annontation是Java5开始引入的新特征,类似与.NET 中的attribute.中文名称一般 ...

  2. java中容器的学习与理解

    以前一直对于java中容器的概念不理解,虽然学习过,但始终没有认真理解过,这几天老师提出了这样一个问题,你怎么理解java中的容器.瞬间就蒙了.于是各种搜资料学习了一下,下面是我学习后整理出来的的一些 ...

  3. Java 8 Lambda表达式学习和理解

    Java 8 Lambda表达式和理解 说明:部分资料来源于网络 时间:20190704 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性.Lambda 允许把函数作为一 ...

  4. 深入理解Java:注解

    注解作用:每当你创建描述符性质的类或者接口时,一旦其中包含重复性的工作,就可以考虑使用注解来简化与自动化该过程. Java提供了四种元注解,专门负责新注解的创建工作. 元注解 元注解的作用就是负责注解 ...

  5. [2]注解(Annotation)-- 深入理解Java:注解(Annotation)自定义注解入门

    转载 http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 深入理解Java:注解(Annotation)自定义注解入门 要深入学习 ...

  6. 深入理解Java:注解(Annotation)自己定义注解入门

    深入理解Java:注解(Annotation)自己定义注解入门 要深入学习注解.我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前.我们就必须要了解Java为我们提供的元注解和相关定义注解的 ...

  7. Java四种引用--《深入理解Java虚拟机》学习笔记及个人理解(四)

    Java四种引用--<深入理解Java虚拟机>学习笔记及个人理解(四) 书上P65. StrongReference(强引用) 类似Object obj = new Object() 这类 ...

  8. [3] 注解(Annotation)-- 深入理解Java:注解(Annotation)--注解处理器

    转载 http://www.cnblogs.com/peida/archive/2013/04/26/3038503.html 深入理解Java:注解(Annotation)--注解处理器 如果没有用 ...

  9. [1] 注解(Annotation)-- 深入理解Java:注解(Annotation)基本概念

    转载 http://www.cnblogs.com/peida/archive/2013/04/23/3036035.html 深入理解Java:注解(Annotation)基本概念 什么是注解(An ...

随机推荐

  1. 第08组 Alpha冲刺(6/6)

    队名:955 组长博客:https://www.cnblogs.com/cclong/p/11913269.html 作业博客:https://edu.cnblogs.com/campus/fzu/S ...

  2. 关于js函数解释(包括内嵌,对象等)

    常用写法: function add(a,b) { return a + b; } alert(add(1,2)); // 结果 3 当我们这么定义函数的时候,函数内容会被编译(但不会立即执行,除非我 ...

  3. 仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表'TableName'中的标识列指定显式值

    当某表的一个列为自动增长列,是无法直接通过insert语句向给字段写入指定值,解决方法: SET IDENTITY_INSERT TABLE_NAME ON; INSERT INTO TABLE_NA ...

  4. Dubbo Filter机制概述

    https://blog.csdn.net/prestigeding/article/details/82085705  从上文可知,在服务的调用或消费端发送请求命令中,Dubbo引入过滤器链机制来实 ...

  5. 修改jar包中的文件

    1.用WinRAR压缩软件打开jar包 2.将修改过的文件直接拖拽并覆盖被替换的文件即可

  6. Oracle 行转列 动态出转换的列

    本文链接:https://blog.csdn.net/Huay_Li/article/details/82924443 10月的第二天,前天写了个Oracle中行转列的pivot的基本使用方法,然后, ...

  7. NodeJS包管理器之Yarn

    一.安装yarn 首选必须先安装好NodeJS,之后可以去yarn官网下载mis安装程序安装.由于NodeJS自带了一个包管理器npm,所以安装yarn更简单的方法是直接使用npm install - ...

  8. 批量实现ssh免密登录

    本节索引 场景分析 ssh免密登录 pssh工具批量管理 SHELL自动化脚本 本篇总结 场景分析 作为一个运维工程师,不是每个人工作的环境都想阿里.腾讯那样,动不动就上亿的PV量,上万台服务器.我们 ...

  9. Consider defining a bean of type 'com.*.*.mapper.*.*Mapper' in your configuration.

    @Mapper 不能加载的问题 Consider defining a bean of type 'com.*.*.mapper.*.*Mapper' in your configuration. 添 ...

  10. element-ui 上传图片 后清空 图片 显示

    使用element-ui组件,用el-upload上传图片,上传图片后再次打开还是会有原来的图片,想要清空原来上传的图片,只需要在组件上绑定ref,在提交成功后的方法里调用this.$refs.upl ...