今天要写一个自定义json解析要用到注解,突然就想起来注解应该是好久之前用到的了,现在想找找也找不到了就想着写一篇博客记录一下吧。
一、Java内置注解
Java内置了三中注解大家也都用过,现在再提一下。
@Override,表示当前的方法定义将覆盖超类中的方法。
@Deprecated,表示弃用的代码,使用注解为它的元素将会发出警告
@SuppressWarnings,关闭不当编译器警告的信息。
二、元注解
1、元注解是可以注解到注解上的注解,是一种基本注解,元注解一共有5种。
2、元注解分类
a、@Retention(它解释说明了这个注解存活的时间) | 它在RetentionPolicy中取值。 SOURCE:注解将被编译器丢弃。 CLASS:注解在class文件中可用,但会被VM丢弃。 RUNTIEM:VM将在运行期间保留注解,所以可以在运行时通过反射使用该注解注解的信息。 |
b、@Documented(和文档有关,能够将注解中的元素包含到javadoc中去) | |
c、@Target(指定注解运用的地方) | 它在ElementType中取值 TYPE:类、接口或者enum声明。 METHOD:方法声明。 PARAMETER:参数声明。 PACKAGE:包声明。 CONSTRUCTOR:构造器声明。 FIELD:域声明。 LOCAL_VARIABLE:局部变量声明。 ANNOTATION_TYPE:可以声明注解的注解。 |
d、@Inherited(表示父类的注解可以被子类继承) | |
e、@Repeatable(可重复,可多次应用的注解) |
三、应用举例
1、 (1)、注解的声明
@Target(ElementType.TYPE) // 注解可以运用的地方
@Retention(RetentionPolicy.RUNTIME) // 注解可以保留到运行的时候
public @interface WillTestAn {
/*
* 注解的属性(成员变量)
* 它的类型必须是种基本类型外加类,接口,注解及它们的数组
*/
WillMsgType type();
}
(2)、注解中的属性
注解中可以添加属性,在使用注解时可以给属性赋值,也可以访问注解中属性的值,举例如下:
//运用到方法上的注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface WillMethodAn {
/**
* 属性拥有一个默认值,使用时可以不给该注解赋值
* 若属性没有默认值,使用注解时必须要给该属性赋值
* @return
*/
String msg() default "this is a method";
}
若注解中只有一个属性且该属性命名为value可以直接给该属性赋值
//运用到属性上的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface WillFieldAn {
/**
* 只有一个属性,且属性命名为value可以直接使用@WillFieldAn(7)
*
* @return
*/
int value();
}
2、注解的使用
(1)、创建一个Animal类
/**
* 使用WillTestAn注解,该注解可以注解类
* @author Will
*
*/
@WillTestAn(type = WillMsgType.TestNumOne)
public class Animal {
/**
* 使用属性注解
*/
@WillFieldAn(5)
public String name="hello";
@WillFieldAn(2)
protected String sex;// 性别
/**
* 使用方法注解
*/
@WillMethodAn
public void walk() {
System.out.println("行走中。。。。。。。。");
}
@WillMethodAn(msg = "i'm a say method.")
public void say() {
System.out.println("want to speak...........");
}
}
(2)、调用注解
//测试类
public class AnTestMain {
public static void main(String[] args) {
useAnnotation(Animal.class);
}
private static void useAnnotation(Class clazz) {
Object object = null;
try {
object = clazz.newInstance();// 生成一个实例
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("检阅注解在类Animal上的关于WillTestAn注解");
boolean hasAn = clazz.isAnnotationPresent(WillTestAn.class);
if (hasAn) {
// 获取class中关于WillTestAn的注解
WillTestAn testAn = (WillTestAn) clazz.getAnnotation(WillTestAn.class);
System.out.println("包含WillTestAn注解,testAn.type():" + testAn.type().toString());
}
System.out.println("检阅注解在方法中的注解");
// 获取class中的方法
Method[] methods = clazz.getDeclaredMethods();
if (methods != null) {
for (Method method : methods) {
WillMethodAn an = method.getAnnotation(WillMethodAn.class);
System.out.println("方法的名字:" + method.getName() + "。注解的内容:" + an.msg());
// 调用方法
try
{
method.invoke(object);
}
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
System.out.println("检阅注解在属性上的注解");
//获取class中的属性
Field[] fields = clazz.getDeclaredFields();
if (fields != null) {
for (Field f : fields) {
WillFieldAn an = f.getAnnotation(WillFieldAn.class);
if (an != null) {
Object obj = null;
try
{
obj = f.get(object);
}
catch (IllegalArgumentException | IllegalAccessException e)
{
e.printStackTrace();
}
System.out.println("变量的名字:" + f.getName() + "。变量的值" + obj + "。注解的内容:" + an.value());
}
}
}
}
}