注解:
概念:给计算机说明程序
注释:
使用文字描述,给程序员看
作用:
编写文档:通过代码里标识的注解生成文档
代码分析:通过代码里标识的注解对代码进行分析
编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查
@Override:检测被标注的方法是否来自父类(接口)的
@Deprecated:该注解标注的内容,表示已过时
@SuppressWarning:压制警告
//压制所有警告
一般在类 前 使用,压制 类 中可能 出现的程序警告
自定义注解:
属性:定义在注解 接口中的抽象 方法
要求:
属性的返回值 类型取值:
- 基本数据类型
- String
- 枚举
- 注解
- 以上类型的数组
元注解: 用于描述注解的注解
@Traget:描述注解能够作用的位置
@Target(value = {ElementType.TYPE}) //表示该注解只能作用于类上
@Retention:描述注解被保留的阶段
@Retention(RetentionPolicy.RUNTIME) //当前的注解,会被保留到class字节码文件中,被JVM读取到
@Documented:描述注解是否被抽取到api文档中
@Inherited:描述注解是否被子类继承
注解:
package notes;
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 notes_method {
String className();
String methodName();
}
使用注解获取类和方法的测试类
package notes;
import java.lang.reflect.Method;
@notes_method(className = "notes.method1",methodName = "method1")
public class test_method {
public static void main(String[] args) throws Exception {
//获取当前使用注解的类对象
Class<?> cls = Class.forName("notes.test_method");
Object o = cls.getConstructor().newInstance();
//获取注解中的类名和方法名
notes_method annotation = cls.getAnnotation(notes_method.class); //获取注解类
String s = annotation.className(); //获取注解中的类名
String s1 = annotation.methodName(); //获取注解中的方法名
//将注解中的类名和方法名加载进内存,再运行
Class<?> aClass = Class.forName(s); //获取类
Object o1 = aClass.newInstance(); //创建类对象
Method method = aClass.getMethod(s1); //获取类方法
method.invoke(o1); //运行类方法
}
}
搭建一个基础框架,检测方法的异常,并写入日志文件:
注释文件代码:
package Frame;
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 Check {
}
检测异常代码文件:
package Frame;
public class Calcultator {
@Check
public void add(){
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));
}
}
检测文件:
package Frame;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class test_Calculate {
public static void main(String[] args) throws IOException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Calcultator cls = Calcultator.class.getConstructor().newInstance();
//相当于 Calcultator cls = new Calcultator ;
Class aClass = cls.getClass();
//通过类的对象,获取字节码文件
Method[] methods = aClass.getMethods();
//获取所有方法
BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt"));
int number = 0;
for (Method method : methods) {
//遍历方法
if(method.isAnnotationPresent(Check.class)) {
//如果方法上有Check注解
try {
method.invoke(cls);
} catch (Exception e) {
number++;
bw.write(method.getName() + "方法出异常了");
bw.newLine();
bw.write("异常的名称:" + e.getCause().getClass().getSimpleName());
//获取异常的原因 . 异常的类 . 异常的类名
bw.newLine();
bw.write("异常的原因:" + e.getCause().getMessage());
bw.newLine();
bw.write("--------------------------");
}
}
}
try {
bw.write("本次出现了" + number + "次异常");
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
日志文件示例:
div方法出异常了
异常的名称:ArithmeticException
异常的原因:/ by zero
--------------------------本次出现了1次异常