java注解-初识
Posted --believe
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java注解-初识相关的知识,希望对你有一定的参考价值。
注解
所谓注解,跟注释类似,用来对代码中的类、方法、属性进行说明。
作用
-
编写文档:通过代码里面标识的注解来生成文档javadoc命令
-
代码分析:可以通过反射机制,得知该类、方法、属性是否有注解。比如可以通过反射,调用getAnnotation函数获取该注解然后进行解析注解中的属性。
-
编译检查:通过注解能够让编译器自动进行编译检查,比如@overide可以检查是否是重载函数
可以暂时理解为一个可以存放数据(注解的属性)的“特殊对象”。他的作用主要体现在可以解析他的属性值。看完《自定义注解》就明白了。
元注解
元注解就是标识注解的注解。也就是系统中定义好的注解,方便我们自定义注解的时候对该自定义注解进行描述。
这里只介绍两种最常用的元注解
@Target
这个元注解表示被描述的注解@Anno的适用范围,也就是说@Anno可以作用于类(TYPE)还是属性(FIELD),又或是方法(METHOD)
@Retention
Retention中文维持,表示被描述的注解的保持时间。我们一般设置为RUNTIME,表示时间是从字节码到JVM读取的时间段都能保持。
自定义注解
package cn.itcast.example.example01;
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)//被修饰的注解保持时间,RUNTIME表示从字节码到jVM读取阶段
public @interface MyAno
//属性列表,本质是方法
String className();
String methodName();
定义注解的格式
- 通过@interface表示是一个注解(本质上是一个接口)
- 注解内部是属性列表,跟定义成员方法一样,返回值+函数名。
- 注解上面是元注解,用来限定该注解的特性,比如作用范围、保持时间等。
解析注解
解析注解就是读取注解的属性。具体步骤
- 创建字节码对象
- 字节码对象调用getAnnotation获取
案例1-通过注解获取类名和方法,并执行类中的方法
步骤
- 获取字节码对象
- 字节码对象调用getAnnotation获取注解对象,然后获取注解对象属性值类名和方法名
- 利用反射执行类中方法
代码
MyAno.java
package cn.itcast.example.example01;
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)//被修饰的注解保持时间,RUNTIME表示从字节码到jVM读取阶段
public @interface MyAno
//属性列表,本质是方法
String className();
String methodName();
Main.java
package cn.itcast.example.example01;
@MyAno(className = "cn.itcast.example.domain.Cat",methodName ="shout" )
public class Main
public static void main(String[] args) throws Exception
Class<Main> cls = Main.class;//通过字节码获取注解对象
MyAno ano = cls.getAnnotation(MyAno.class);//获取注解对象
String cn = ano.className();
String mn = ano.methodName();
Class<?> cls1 = Class.forName(cn);
Object o = cls1.getConstructor().newInstance();
cls1.getMethod(mn).invoke(o);
Cat.java
package cn.itcast.example.domain;
public class Cat
private String name;
public Cat()
public Cat(String name)
this.name = name;
public String getName()
return name;
public void setName(String name)
this.name = name;
public void shout()
System.out.println("喵喵喵");
Dog.java
package cn.itcast.example.domain;
public class Dog
private String name;
public Dog(String name)
this.name = name;
public String getName()
return name;
public void setName(String name)
this.name = name;
public Dog()
public void shout()
System.out.println("哇哦哇哦");
案例2-通过注解实现测试框架,测试Calculator中的各个方法
步骤
- 自定义一个方法注解
- 在需要测试的方法上加上注解
- 在测试类中利用反射机制获取Calculator字节码对象,获取该对象的所有方法对象。
- 方法对象调用getAnnotation获取注解,根据注解有无执行该方法对象。(主要利用了反射机制)
代码
Calculator.java
package cn.itcast.example.example02;
public class Calculator
//加法
@Check
public void add()
String str = null;
str.toString();
System.out.println("1 + 0 =" + (1 + 0));
//减法
@Check
public void sub()
System.out.println("1 - 0 =" + (1 - 0));
//乘法
@Check
public void mul()
System.out.println("1 * 0 =" + (1 * 0));
//除法
@Check
public void div()
System.out.println("1 / 0 =" + (1 / 0));
public void show()
System.out.println("永无bug...");
Check.java
package cn.itcast.example.example02;
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 Check
TestCheck.java
package cn.itcast.example.example02;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestCheck
public static void main(String[] args) throws Exception
Calculator calculator = new Calculator();
Class cls = calculator.getClass();
Method[] declaredMethods = cls.getDeclaredMethods();
// FileWriter fw = new FileWriter("bug1.txt");
BufferedWriter fw = new BufferedWriter(new FileWriter("bug.txt"));
int sum=0,erorNum=0;
for (Method declaredMethod : declaredMethods)
// System.out.println(declaredMethod);
Check annotation = declaredMethod.getAnnotation(Check.class);
//如果有注解
if(null!=annotation)
sum++;
try
declaredMethod.invoke(calculator);
catch (Exception e)
fw.write(declaredMethod.getName()+"出异常了");
fw.newLine();
fw.write(e.getCause().toString());
fw.newLine();
fw.write("---------------");
fw.newLine();
erorNum++;
fw.write("一共测试了"+sum+"个函数");
fw.newLine();
fw.write("出错了"+erorNum+"个函数");
fw.newLine();
fw.flush();
fw.close();
总结
实际开发过程中我们一般是使用注解,一般不会去自定义注解,但是我们需要知道注解本质就是一个接口,在接口中定义一些方法列表(在注解中称为属性列表)。
可以利用反射机制获取注解,从而解析注解得到里面的属性。
以上是关于java注解-初识的主要内容,如果未能解决你的问题,请参考以下文章