Java的自定义注解使用实例
概念
Java有五个元注解,自动继承java.lang.annotation.Annotation。
什么是元注解,可以理解为其他普通注解进行解释说明
@Target 该注解的使用范围,限定应用场景。枚举类 ElemenetType 中
- TYPE:类,接口
- FIELD:字段,枚举的常量
- METHOD:函数(方法)
- PARAMETER:参数
- CONSTRUCTOR:构造函数
- ANNOTATION_TYPE:注解类型
- LOCAL_VARIABLE:局部变量
- PACKAGE:包
@Retention 该注解的生存周期,相当于时间戳。枚举类型 RetentionPolicy 中
- SOURCE:在源文件中有效,编译后会被丢弃(如@Override,@Deprecated)
- CLASS:在class文件中有效,在jvm丢弃
- RUNTIME:在运行时有效,class文件保留,jvm运行时保留(很多框架运用反射调用)
@Documented
javadoc文档生成工具的使用
@Inherited
允许子类继承父类中的注解。
@Repeatable
同一种注解可多次使用
作用
- 注释,解释,通过代码的标识元数据生成doc文档;
- 使用反射,通过代码标识的元数据对代码进行分析;
- 编译检查,通过代码标识的元数据让编译器进行基本检查。
实例
定义一个普通的注解,
public @interface Test
{ }
使用我们自定义的注解
@Test
public class Person
{
@Test
private String name; @Test
private int age; @Test
public void say()
{
System.out.println("Hello,Java Annotation");
}
}
@Target(ElementType.PACKAGE) 注解作用的目标>包
这个注解要理解什么是友好声明类和包常量,包中有很多的内部访问的类或常量,就可以统一的放到友好声明类中,这样就方便,而且集中管理,减少friendly类到处游走的情况。
可以参考这个 https://www.cnblogs.com/DreamDrive/p/5428573.html
import java.lang.annotation.ElementType;
@Target(ElementType.PACKAGE)
public @interface Test
{
}
@Test
package test; class Person
{ private String name; private int age; public void say()
{
System.out.println("Hello,Java Annotation");
}
}
@Target(ElementType.CONSTRUCTOR) 注解作用的目标>构造函数
package test; import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.CONSTRUCTOR)
public @interface Test
{ }
package test; public class Person
{ private String name; private int age;
@Test
public Person()
{ } public void say()
{
System.out.println("Hello,Java Annotation");
}
}
其他范围就不一一列举,都是相同的。
@Retention(RetentionPolicy.RUNTIME) 生存周期
代码运行时动态获取注解的信息
package test; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test
{ }
package test; public class Person
{ private String name; private int age;
@Test
public Person()
{ } public void say()
{
System.out.println("Hello,Java Annotation");
}
}
注解的属性-->成员变量
方法名是成员变量的的名字,变量的类型是他的返回值。
package test; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test
{
public int age() default ; public String name() default ""; public String className();
}
package test; import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method; @Test(age = 15,name = "zhangsan",className = "高三(3)班")
public class Person
{ private String name; private int age; public Person()
{ } private void say()
{
System.out.println("Hello,Java Annotation");
}
}
既然给了注解,我们要做的工作必然是要提取注解上面的内容,要拿到这些注解就要用到反射。
package test; import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method; @Test(age = 15,name = "zhangsan",className = "高三(3)班")
public class Person
{private String name; private int age; public Person()
{ } private void say()
{
System.out.println("Hello,Java Annotation");
} public static void main(String[] args)
{
boolean hasAnnotation = Person.class.isAnnotationPresent(Test.class); if (hasAnnotation)
{
Test test = Person.class.getAnnotation(Test.class); System.out.println("age:" + test.age());
System.out.println("name:" + test.name());
System.out.println("className:" + test.className());
}
}
}
输出结果
age:15
name:zhangsan
className:高三(3)班
对于类的属性和方法,都是同样的道理。
成员注解
package test; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Field
{
public String name();
}
函数注解
package test; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Method
{
public String say();
}
Person类
package test; import java.lang.annotation.Annotation; @Test(age = 15,name = "zhangsan",className = "高三(3)班")
public class Person
{
@Field(name = "lisi")
private String name; private int age; public Person()
{ }
@Method(say = "hello")
private void say()
{
System.out.println("Hello,Java Annotation");
} public static void main(String[] args)
{
boolean hasAnnotation = Person.class.isAnnotationPresent(Test.class); if (hasAnnotation)
{
Test test = Person.class.getAnnotation(Test.class); System.out.println("age:" + test.age());
System.out.println("name:" + test.name());
System.out.println("className:" + test.className());
} try
{
java.lang.reflect.Field field = Person.class.getDeclaredField("name"); field.setAccessible(true); Field check = field.getAnnotation(Field.class); if (check != null)
{
System.out.println("check value:" + check.name());
} java.lang.reflect.Method method = Person.class.getDeclaredMethod("say"); if (method != null)
{
Annotation[] ans = method.getAnnotations();
for (int i = 0; i < ans.length; i++)
{
System.out.println("method annotation:" + ans[i].annotationType().getSimpleName());
}
} } catch (NoSuchFieldException e)
{
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
} }
}
输出
age:15
name:zhangsan
className:高三(3)班
check value:lisi
method annotation:Method
可以看出我们获取了注解上的值,现在都没有实际意义,我们可以用注解来做些什么?
这些我没办法给出确切答案,只能说根据各人需求去合理利用注解。
实例
注解参数赋值
@Test注解
package test; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Test
{
String value();
}
Person类属性赋值
package test; import org.apache.poi.ss.formula.functions.T; import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method; public class Person
{
@Test("zhangsan")
private String name; @Test("15")
private int age; public Person()
{ } private void say()
{
System.out.println("Hello,Java Annotation");
} @Override
public String toString()
{
return "name = " + name + "\n" + "age = " + age;
} public static void main(String[] args)
{
Person person = new Person();
try
{
//取得成员变量的值
Field field = Person.class.getDeclaredField("name");
//打开权限
field.setAccessible(true);
//判断属性是否有注解
if (field.isAnnotationPresent(Test.class))
{
//获取属性上的注解值
Test test = field.getAnnotation(Test.class);
String name = test.value();
//赋值
field.set(person,name);
} Field field1 = Person.class.getDeclaredField("age");
field1.setAccessible(true);
if (field1.isAnnotationPresent(Test.class))
{
Test test = field1.getAnnotation(Test.class);
int age = Integer.valueOf(test.value());
field1.set(person,age);
}
System.out.println(person); }catch (Exception e)
{
e.printStackTrace();
} }
}
输出
name = zhangsan
age = 15
用注解去检查函数等等。。
lz不善于用语言表达,所以可能有很多人没看懂,可以看下
一个大佬讲解的注解说明(简单易懂)
https://blog.csdn.net/briblue/article/details/73824058
Java的自定义注解使用实例的更多相关文章
- Java实现自定义注解开发
Java实现自定义注解开发 一直都对注解开发挺好奇的,最近终于有时间自己实践了一把,记录一下 万一后期会用到呢 哈哈哈 首先我们了解一下自定义注解的标准示例,注解类使用 @interface 关键字修 ...
- java自定义注解知识实例及SSH框架下,拦截器中无法获得java注解属性值的问题
一.java自定义注解相关知识 注解这东西是java语言本身就带有的功能特点,于struts,hibernate,spring这三个框架无关.使用得当特别方便.基于注解的xml文件配置方式也受到人们的 ...
- 注解:java 自定义注解应用实例
本例子旨在使用自定义注解为实体打上标记,为自动生成 sql 提供依据,模拟 hibernate 的注解,至于注解的原理自己搜吧 1.定义 Table 注解 package test; import j ...
- [转] Java @interface 自定义注解
[From] http://blog.csdn.net/afterlife_qiye/article/details/53748973 1. 注解的好处 注解可以替代配置文件完成对某些功能的描述,减少 ...
- Java Annotation自定义注解详解
在开发过程中总能用到注解,但是从来没有自己定义过注解.最近赋闲在家,研究整理了一番,力求知其然知其所以然. 本文会尝试描述什么是注解,以及通过一个Demo来说明如何在程序中自定义注解.Demo没有实际 ...
- Java利用自定义注解、反射实现简单BaseDao
在常见的ORM框架中,大都提供了使用注解方式来实现entity与数据库的映射,这里简单地使用自定义注解与反射来生成可执行的sql语句. 这是整体的目录结构,本来是为复习注解建立的项目^.^ 好的,首先 ...
- Java基于自定义注解的面向切面的实现
目的:实现在任何想要切的地方添加一个注解就能实现面向切面编程 自定义注解类 @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retentio ...
- java学习--自定义类的实例的大小比较和排序
我们知道Object类有一个equals方法,用于比较两个对象是否相等 我们只要在自定义类中重写了equals方法(若不重写就是比较两个实例的地址,相当于==)就可以用来比较该类的两个实例是否相等 问 ...
- java/springboot自定义注解实现AOP
java注解 即是注释了,百度解释:也叫元数据.一种代码级别的说明. 个人理解:就是内容可以被代码理解的注释,一般是一个类. 元数据 也叫元注解,是放在被定义的一个注解类的前面 ,是对注解一种限制. ...
随机推荐
- JDK 源码分析(4)—— HashMap/LinkedHashMap/Hashtable
JDK 源码分析(4)-- HashMap/LinkedHashMap/Hashtable HashMap HashMap采用的是哈希算法+链表冲突解决,table的大小永远为2次幂,因为在初始化的时 ...
- SOFA 源码分析— 自定义路由寻址
前言 SOFA-RPC 中对服务地址的选择也抽象为了一条处理链,由每一个 Router 进行处理.同 Filter 一样, SOFA-RPC 对 Router 提供了同样的扩展能力. 那么就看看 SO ...
- LinkedList源码
1.介绍及注意事项 链表由Josh Bloch书写,属于Java集合框架中的一种,LinkedList实现的是双链表,实现了所有的链表操作,可能够实现所有元素(包括)的基本操作. 链表是非线程同步的, ...
- Linux系统中常见文件系统格式
Windows常用的分区格式有三种,分别是FAT16.FAT32.NTFS格式. 在Linux操作系统里有Ext2.Ext3.Linux swap和VFAT四种格式. FAT16: 作为一种文件名称, ...
- C/C++静态代码安全检查工具
静态代码安全检查工具是一种能够帮助程序员自动检测出源程序中是否存在安全缺陷的软件.它通过逐行分析程序的源代码,发现软件中潜在的安全漏洞.本文针对 C/C++语言程序设计中容易存在的多种安全问题,分别分 ...
- Java工具类 通过ResultSet对象返回对应的实体List集合
自从学了JDBC用多了像一下这种代码: List<xxx> list = new Array<xxx>(); if(rs.next()){ xxx x = new xxx(); ...
- Atlas的优缺点及测试结论
优点 1,实现了读写分离(并通过hint/*master*/可强制走主库,并且加入了权重配置可进行读的负载均衡 2,自身维护了一套连接池,减少了创建连接带来的性能消耗 3,支持DB动态上下线,方便横向 ...
- 数码相框(LCD、I2C)
一:项目介绍 该项目最终实现的功能很简单,手指在触摸屏左滑(下一张图片),右滑(上一张图片) 1.1软硬件资源 硬件:pc机,ARM Cortex-A9开发板 软件:linux ...
- @SpringBootApplication注解理解
@SpringBootApplication包含三个有用的注解,包括 @SpringBootConfiguration:看源码其实就是@Configuration,表示当前类是一个配置类,就像xml配 ...
- XamarinForm Effects 调用事件
原文地址 在Xamarin.Forms控件中实现底层多点触控跟踪. 一个effect可以定义和调用一个事件,在底层本地视图中发出信号的变化.这篇文章演示如何实现底层多点触控跟踪,以及如何生成信号触摸活 ...