
框架设计的灵魂 框架是半成品软件,简化编码
概念:将类的各个组成部分封装为其他对象,就是反射机制
Java代码:三个阶段:
1、第一阶段:Source源代码阶段:代码在磁盘上 .java类文件 ------>.class字节码文件
2、第二阶段:Class类对象阶段:ClassLoader类加载器,将字节码文件加载到内存:Class类对象:Fiilds对象,Constructor对象,Method对象
3、第三阶段:Runtime运行时阶段:new 类();
优点:1、可以在程序运行过程中,操作这些对象
2、解耦代码
获取Class对象的方式Class对象只有一个也即是 .class字节码文件只会加载一次
1、对于第一阶段:Class.forname(“全类名”);将字节码文件加载到内存里,返回Class对象
- 多用于配置文件,将类名定义在配置文件中,读取文件,来加载类
2、对于第二阶段:类名.Class:通过类名的属性class获取
- 多用于参数的传递
3、第三阶段:对象。getClass();该方法在Object中定义,故所有对象都有该方法
- 多用于对象的获取字节码的方式
tips:ClassNotFoundException一般都是类名写错了
Class对象的功能概念:
- 注释:文字解释程序功能,给程序员看的 - 注解:也叫元数据 代码级别的说明,1.5后新特性,对程序元素进行说明注释,给程序看的
作用分类:
主要使用其代码分析的功能:
使用注解预定义注解
自定义注解
格式
元注解
publi @inerface 注解名称{}
public @interface MyAno{
int age();
String name() default "zhangsan";
}
本质:注解本质就是一个接口,该接口默认继承Annotation接口
注解的属性:接口中可以定义的抽象方法
属性的返回值类型:除了以下类型,其他都不行
定义了属性,在使用时需要给属性赋值
元注解:用于描述注解的注解
解析注解:使用注解中定义的属性
注解替换配置文件
public class Demo{
public void show(){
System.out.println("show running");
}
}
@Target({ElementType.TYPE})
@Tetention(RententPolicy.RUNTIME)
public @interface Pro{
String className();
String methodName();
}
@Pro(className="com.mytest.Demo",methodName="show")
public class ReflectTest{
public static void main(Sring[] args){
//解析注解
//获取该类的字节码文件
Class reflectTestClass = ReflectTest.class;
//通过具体的注解类名获取上边的注解对象(在这个大类的字节码文件中所有信息都有的)
//在内存中生成了一个该注解接口的子类实现对象ProImpl,而且将响应的数据返回
Pro an = reflectTestClass.getAnnotation(Pro.class);
//直接调用注解对象中的抽象方法,获取返回值
String clsaaName = an.className();//获取到了数据"com.mytest.Demo"
String methodName = an.methodName();
//加载该类进内存
Class cls = Class.forName(className);
//创建对象
Object obj = cls.newInstance();
//获取方法对象
Method method = cls.getMethod(methodName);
//执行方法
method.invlke(obj);
}
}
总结
1、获取注解定义的位置的对象(Class,Method,Field)
2、获取指定的注解
getAnnotation(注解.class)
在内存中生成一个该注解接口的子类实现对象
调用注解中的抽象方法获取配置的属性值
//要被测试的类,也就是要加@Chack测试注解的类
public class Calculator{
//@Check
public int add(){
System.out.println(1+0);
}
//@Check
public int sub(){
System.out.println(1-0);
}
//@Check
public int mul(){
System.out.println(1*0);
}
//@Check
public int div(){
System.out.println(1/0);//这个是有异常的
}
}
public class TestCheck{
public static void main(String[] args){
//创建计算器对象
Calculator c = new Calculator();
//获取字节码文件
Class cls = c.getClass();
//获取所有方法
Method[] methods = cls.getMethods();
int number = 0;//出现异常的次数
BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt"));
for(Method method : methods){
//判断方法上是否有Check注解
if(method.isAnnotationPresent(Check.class)){
try{
method.invoke(c); //捕获执行方法时的异常
}catch(Exception e){
//记录异常信息到文件中
number++;
bw.write(method.getName()+"方法出现异常了");
bw.newLine();
bw.write("异常的名称"+e.getCause().getSimpleName());
bw.newLine();
bw.write("异常的原因"+e.getCause().getMessage());
bw.newLine();
bw.write("------------------------");
bw.newLine();
}
}
}
bw.write("本次测试一共出现"+num+"次异常");
bw.flush();
bw.close();
}
}