1_Java基础强化(反射 类对象 注解)

Day1 基础强化

一、代码测试方法(junit单元)

  • a.测试分类:黑盒测试、白盒测试
  • b.Junit 测试步骤

1.创建测试类:包名 xx.xx.xx.test; 测试类名 类名+Test
2.定义测试方法:可以独立运行 方法名 test+测试方法名 返回值 void 参数列表 空参
3.判定结果:用 断言操作 处理(方法:Assert.assertEquals(期望结果,运算结果))

  • c.注意:就是点击小灯泡导入 Junit包
  • d.方法修饰符:@Before 修饰的方法会在测试方法之前被自动执行(初始化方法)

@After 修饰的方法会在测试方法执行之后自动执行(释放资源)
@Test 测试方法,在这里可以测试期望时间和超时时间

二、 反射概述

  • a.意义:(后期补上)用来构造框架,在框架上进行软件开发,简化编码
  • b.获取Class对象的三种方式(都是返回Class对象)

1.Class.forName(“全类名(包路径+类名)”)
2.类名.class
3.对象.getClass()
说明:其实就是类对象,同一个类的类对象是相同的,不同的类的类对象是不同的

三、反射Class对象的功能(这些获取变量的相关方法都是用来获取一些没有指定实例化对象的相关对象;这里包括类对象的获取方法也是同样的道理)

  • a.获取成员变量(Filed对象)
  • Field[] getFields() :获取所有public修饰的成员变量
  • Field getField(String name) 获取指定名称的 public修饰的成员变量
  • Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
  • Field getDeclaredField(String name) 和上面不同的是可以对任意权限修饰符 修饰的field对象进行操作,但是不一定能获取,需要配合暴力反射
    相关方法:
  1. 设置值
  • void set(Object obj(这里是指创建字节码对象的类的实例化对象), Object value)
  1. 获取值
  • get(Object obj) //参数是指类的实例化对象
  1. 忽略访问权限修饰符的安全检查
  • setAccessible(true):暴力反射
  • b.获取构造方法(Constructor对象)
  • Constructor<?>[] getConstructors()
  • Constructor getConstructor(类<?>… parameterTypes) 黄体参数其实就是目标方法中参数列表的重写 示例:String.class
  • Constructor getDeclaredConstructor(类<?>… parameterTypes)
  • Constructor<?>[] getDeclaredConstructors()
    相关方法:
  • 创建对象:
  • T newInstance(Object… initargs)
  • c.获取成员方法(Method对象)
  • Method[] getMethods() 只能获取public方法,但是可以获取继承的父类或者接口的方法
  • Method getMethod(String name, 类<?>… parameterTypes)
  • Method[] getDeclaredMethods() 可以获取任何权限修饰符修饰的方法,但是不能获取父类或者父接口中的方法
  • Method getDeclaredMethod(String name, 类<?>… parameterTypes)
    相关方法:
  • 执行方法:
  • Object invoke(Object obj, Object… args)
  • d.获取类名(包路径+类名 而不仅仅是类名)
  • String getName()
  • e.意义:通过创建字节码对象(Class对象),进而获取相关类的成员(方法、变量)对象,通过这些成员对象我们可以对这些成员进行

读写操作。(不过写操作通常是需要三个对象:Class对象、成员对象、相关类的实例化对象)

四、反射案例(自己搭建一个“框架”,可以帮我们创建任意类的对象,并且执行其中任意方法)

  • a.(在以后补充)
  • b.实现方式:配置文件|反射
  • c.步骤
  1. 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
  2. 在程序中加载读取配置文件
  3. 使用反射技术来加载类文件进内存
  4. 创建对象
  5. 执行方法
  • d.实际代码(创建的pro.properties 文件(目前谨慎点的话就创建与src目录同级))

//步骤一:1.创建相应的类加载器 (通过 本类名.class.getClassLoader);2.通过类加载器或取配置文件的字节流;
ClassLoader classLoader = reflectT.class.getClassLoader();
InputStream resourceAsStream = classLoader.getResourceAsStream(“pro.properties”);
//步骤二:1.创建properties集合(这个集合比较特别,专门用来处理.properties文件);2.通过properties集合的特殊方法 void load(InputStream in),这样就直接可以获取通过配置文件获取双列集合,从而省去间接的通过字节流 read()方法获取文件内容的繁杂步骤
Properties pro = new Properties();
pro.load(resourceAsStream);
//步骤三:1.获取 包名+类名 也就是为了创建类对象; 2.获取方法名 为了获取方法对象
String className = pro.getProperty(“className”);
String methodName = pro.getProperty(“methodName”);
//步骤四:1.通过类对象获取相应的方法对象; 2.最后其实就是创建实例化对象调用方法了,这里用到了一个老方法 类实例化对象 newInstance()(虽然已经过时,但是可以直接获取实例化对象)
Class<?> aClass = Class.forName(className);
Method method = aClass.getMethod(methodName);
method.invoke(aClass.newInstance());
相关新的方法|类
1.获取类的文件夹加载器:ClassLoader ---- 本类类名.class.getClassLoader
2.通过文件夹加载器获取字节流:ClassLoader对象.getResourceAsStream(String 配置文件路径)
3.直接将字节流写入集合:Properties实例对象.load(字节流对象)
4.一个已经废弃了的方法,但是可以直接通过类对象创建相关类的实例化对象: 类对象.newInstance()

第四堂课 注解(注意哦!这不是注释)

一、常见注解

  • a.@Overide 检测该注解标注的方法是否是继承自父接口
  • b.@Deprecated 表示方法已经过时
  • c.@SuppressWarmings 压制警告(通常写在类上@SuppressWarmings(“all”),压制所有的警告)

二、自定义注解

  • a.格式

元注解
public @interface MyAnno{
}

  • b.注解的本质

public interface MyAnno extends java.lang.annotation.Annotation {
}
说明:注解本质上就是一个接口,该接口默认继承java.lang.annotation.Annotation接口

  • c.注解的属性:接口的抽象方法

要求:1.属性返回值:基本数据类型|String|枚举|注解|以上类型的数组
2.定义了属性,在使用时需要个属性赋值。

  • a.如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值。

  • b.如果只有一个属性需要赋值,并且属性名是value,则value可以省略,直接在使用该注解时定义值即可。

  • c.在这里数组赋值时是比较特殊的,需要用大括号进行赋值。如果数组织有一个值,那么大括号可以省略。

  • d.疑惑点:1.这里的枚举类型不太了解 2.这里的注解类型肤质有点蒙

  • e.这里说明一下注解|枚举类型在注解中的定义: 注解示例 MyAnno2 anno2(); 枚举示例 Person per();

  • d.元注解(与注解略有不同,本质相同|也是注解),用来描述注解的注解

@Target:描述注解能够作用的位置
使用(只写了该如何赋值):枚举类型[]|数组 ElementType.TYPE|表示注解只能作用再类上、
ElementType.METHOD|表示该类只能作用在方法上、
ElementType|FIEID可以作用于成员变量上
@Retention:描述注解被保留的阶段(3个阶段 source|classs|runtime)
使用 RetentionPolicy.RUNTIME 表示注解会一直保留到3个阶段都结束
@Documented:描述注解是否被抽取到API文档中
@Inherited:描述注解是否被子类继承(被该元注解描述的注解所修饰的类,任何继承该类的子类都将会继承这个被元注解修饰的注解)

二、一些课外操作

  • a.通过带注解的java文件生成java的API文档

1.写一个带有多个注解的java 接口|类 然后另存为桌面中的新建文件夹中;
2.打开cmd窗口,进入.java文件对应的文件夹中,然后输入 javadoc 文件名.java 编译后,生成API网页;
3.如果出现乱码,那么就通过nodpad++将java文件重新编译成相应编码的文件,并且再次使用 cmd窗口再次 javadoc 编译文件。

  • b.通过cmd窗口进行java的 反编译

1.先编译java文件 javac 文件名.java
2.在进行反编译 javap 文件名.class

  • c.枚举类型的一般定义

直接定义常量:示例 P1,P2;

三、通过注解来获取配置文件

  • a.实操演示

//步骤一:获取包含指定注解(用于获取配置文件类似信息的注解)的类
Class aClass = ReflectTest.class;
//步骤二:获取这个注解的对象,通过含有注解的类来获取,注意使用的方法
Myano annotation = aClass.getAnnotation(Myano.class);
//实质上的过程,内存中内部通过这个方法创建了一个实现这个注解接口的类,并且返回了实例化对象
/*
public class 实现类 implements Myano{
public String className(){
return “注解初始化时赋予的值”;
}


  • }

*/
//步骤三:通过注解对象调用方法即可
String className = annotation.className();
String methodName = annotation.methodName();
System.out.println(className + methodName);

  • b.相关方法:

T(注解实现类的实例化对象) 类对象.getAnnotation(注解名.class) 返回的是一个注解接口的实现类的实例化对象

四、简单的测试框架

  • a.示例:

//综合实践:通过注解测试方法
int number = 0;
//步骤一:获取方法对象
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(“D:\JavaSource\AllProjects\LearningJava\javaWeb\src\day1\Annovacation\Annocation\Caculator\rizzhi.txt”));
caculator caculator = new caculator();
Class<? extends day1.Annovacation.Annocation.Caculator.caculator> aClass = caculator.getClass();
Method[] methods = aClass.getMethods();//最好用Declare获取方法,再用暴力反射,否则会遗漏一些方法
//步骤二:遍历方法,判断是否包含注释:接着捕获异常;输出到文件中打印;
for (Method method : methods) {
if (method.isAnnotationPresent(Check.class)) {
try {
method.invoke(caculator);
} catch (Exception e) {
number++;
bufferedWriter.write(method.getName() + “方法出现异常!”);
bufferedWriter.newLine();
bufferedWriter.write(“异常的名称:” + e.getCause().getClass().getSimpleName()/+e.getMessage()+e.toString()/);
bufferedWriter.newLine();
bufferedWriter.write(“异常的原因:” + e.getCause().getMessage());
bufferedWriter.newLine();
bufferedWriter.write("------------------");
bufferedWriter.newLine();
}
}
}
bufferedWriter.write(“异常出现的次数:” + number);
bufferedWriter.close();

  • b.使用到的新方法:

1.public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) 判断是否包含这个注解(这个方法)Method类是java.lang.reflect.AccessibleObject的子类
2.public synchronized Throwable getCause() 返回…
3.public String getSimpleName() Class类中的方法,返回异常名称

一些理解:
1.简单的测试框架综合案例中我学到了什么?首先,最表面的,可以用来测试一些被注解修饰的方法;深层次的(本质的):我们可以
将注解作为一个标记,用来查找遍历|筛选 我们应该学会的是这个东西。(说明:成员变量对象|构造方法对象|成员方法对象
都可以将注解作为自己的标记)
2.在本章节中,我们在注解的学习这一块内容中,我们主要是需要学会:1.通过注解中定义的带返回值的方法来获取类似配置文件中的
信息;2.学会用注解来标记成员属性(可以通过类对象获取成员,在通过成员调用判断注解是否修饰自己来过滤筛选)
3.在本章节,我们需要学会基本的配置文件的配置,通过properties集合和一些流来获取配置文件中的信息。掌握Properties双列集合
的特殊性质,直接读取配置文件,通过对应的格式自动分配键值对对象。(用到 void load(properties对象))
4.Junit测试包,其时是对一个方法非常细致的测试,细腻。

发布了21 篇原创文章 · 获赞 9 · 访问量 1491

猜你喜欢

转载自blog.csdn.net/qq_43230007/article/details/104155774
今日推荐