注解也叫注释 英语单词:Annotation
注解Annotation是一种数据类型编译后生成.class文件
注解定义语法格式
[修饰符列表] @interface 注解类型名{
注解可以设置属性 (如果只有一个属性建议将属性名设置为value,如果属性名为value则使用时属性名可以省略)defaule (设置属性默认值)
}
需求:
假设有这样一个注解叫做:@id
这个注解只能出现在类上面当这个类上有注解时
要求这个类中必须有一个int类型的id属性,如果没有这个属性则报异常如果有则正常执行
首先定义一个id注解
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 id {
}
//这个注解@id用来标注类,被标主的类中必须有一个int类型的id属性
//没有就报异常
定义一个类在类上标记注解
@id
public class user {
//属性后面如果加上default 则表示设置属性默认值
int id;
String name;
}
创建测试
import java.lang.reflect.Field;
public class AnnotatinoTest01 {
public static void main(String[] args) throws Exception {
//获取类
Class userClass=Class.forName("com.annotation.user");
//判断类上是否存在@id注解
if(userClass.isAnnotationPresent(id.class)){
//如果类上有@id注解则要求类必须有int类型的id属性
//如果没有int类型的id属性则报异常
//获取类的属性
Field[] fields=userClass.getDeclaredFields();//getDeclaredFields()获取全部属性并返回在field数组// 中
boolean isok=false;
for(Field field:fields){
//getName()获取属性的名字 .getType().getSimpleName()获取属性的类型
if("id".equals(field.getName())&&"int".equals(field.getType().getSimpleName())){
//表示这个类是合法的类有@id注解则这个类必须有int类型的id属性
isok=true;
}
}
//判断是否合法
if(!isok){
throw new HasntIdPropertyException("被@id注解的类中必须有一个int类型的id属性");
}
}
}
}
自定义异常
/**
* 自定义异常
*/
public class HasntIdPropertyException extends RuntimeException {
public HasntIdPropertyException(){
}
public HasntIdPropertyException(String S){
super(S);
}
}
运行结果
当类中有int类型的id属性时正常运行
当类中没有int类型的id属性时抛出异常
通过注解在不改变任何代码的前提下,创建任意对象执行任意方法
先创建自定义注解
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 pro {
String className();//描述要执行的类名
String methodName();//描述要执行的方法
}
定义要创建的类
package com.DW.test;
public class Demo {
public void show(){
System.out.println("真不错----");
}
}
编写测试类
import java.lang.reflect.Method;
//将要创建的类的全类名赋值给className
//将要执行的类的方法名给methodName
@pro(className = "com.DW.test.Demo",methodName ="show" )
public class test {
public static void main(String[] args) throws Exception {
//1.解析注解
//获取该类的字节码文件
Class<test> testClass = test.class;
//获取该类上的注解对象
pro annotation = testClass.getAnnotation(pro.class);
//调用注解对象中定义的抽象方法获取返回值
String className = annotation.className();//返回值就是com.DW.test.Demo
String methodName = annotation.methodName();//返回值就是show
//加载类进内存
Class aClass = Class.forName(className);
//创建对象
Object o = aClass.newInstance();
//获取方法对象
Method method = aClass.getMethod(methodName);
//执行方法
method.invoke(o);
}
}
使用注解来对程序进行判断是否有错误如果有错误则创建一个错误日志
先定义一个注解来标记被测试类的方法
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.METHOD)
public @interface test {
}
创建要被测试的类并在要测试的方法上加上注解
/**
* 自定义一些方法用注解标记方法
*/
public class CustomMetgods {
@test
public void add(){
System.out.println("1+1="+(1+1));
}
@test
public void division(){
System.out.println("3/0="+(3/0));
}
}
创建测试类
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
/**
* 简单测试框架
* 当主方法执行自动检测被测试方法(加注解的方法)是否有异常
*/
public class Dome {
public static void main(String[] args) throws IOException {
//创建要被测试的对象
CustomMetgods c=new CustomMetgods();
//获取字节码文件
Class aClass = c.getClass();
//获取所有的方法
Method[] methods = aClass.getMethods();
int count=0;//表示出现错误的次数
//创建错误信息文件
BufferedWriter bw=new BufferedWriter(new FileWriter("bug.txt"));
for (Method method : methods) {
//判断方法上是否有test注解
if(method.isAnnotationPresent(test.class)){
//有test注解就执行
try {
method.invoke(c);
} catch (Exception e) {
//出现错误记录错误信息
count++;
bw.write(method.getName()+"方法出现异常!");
bw.newLine();
bw.write("异常名称"+e.getCause().getClass().getSimpleName());
bw.newLine();
bw.write("异常原因"+e.getCause().getMessage());
bw.newLine();
bw.write("------------------");
bw.newLine();
}
}
}
bw.write("本次测试出现"+count+"次异常");
bw.flush();
bw.close();
}
}
运行结果
生成一个bug.txt文件来记录错误信息