JavaWebDay00
课程大纲
1、单元测试Junit
2、反射机制
3、注解
额外涉及知识点: 类的加载器 //pro.properties文件写在src路径当中
ClassLoader classLoader = 当前类.class.getClassLoader();
InputStream is = classLoader.getResourceAsStream("pro.properties");
小黑窗口骚操作
在.java文件所在的目录当中,启动小黑窗口。采用指令: javadoc 类名称.java 回车 生成 doc文档。
第一章 Junit单元测试
1、测试的分类
A.黑盒测试:不需要写代码
B.白盒测试:需要编写代码(Junit单元测试属于白盒)
2、Junit单元测试的步骤
A.定义测试类(包名称: xxx.xxx.test , 类名称: 需要测试名称Test)
B.定义测试方法(可以独立运行,名称:test测试的方法名称,返回值和参数列表空)
C.给方法加注解 @Test
D.添加Junit的依赖
3、判定结果
A.红色: 失败
B.绿色: 成功
C.使用断言操作(预言结果是否正确
断言代码: Assert.assertEquals(期待结果,真实结果);
4、测试方法执行前后注解
A. @Before 在所有测试方法执行前,方法上添加注解(用于数据初始化)
B. @After 在所有测试方法执行后,方法上添加注解(用于释放资源)
第二章 反射
1、反射的含义
A.框架设计的灵魂(框架是半成品软件,我们可以在框架的基础上进行二次开发)
B.反射将类的组成部分(成员变量,成员方法,构造方法)封装成为其他对象
2、获取字节码对象方式
A.方式1: Class.forName("包名称.类名称");
B.方式2: 类名称.class
C.方式3: 对象.getClass();
3、字节码相关的获取功能
A、获取构造方法
Constructor[] getDeclaredConstructors() //获取所有的包含私有构造方法
Constructor getDeclaredConstructor(String name) //获取指定包含私有构造方法
B、获取成员变量
Field[] getDeclaredFields() //获取所有的包含私有成员变量
Field getDeclaredField(String name) //获取指定包含私有成员变量
C、获取成员方法
Method[] getDeclaredMethods() //获取所有的包含私有成员方法
Method getDeclaredMethod(String name) //获取指定包含私有成员方法
D、获取类名称
String getName()
4、案例介绍
A. 需要反射的类
package com.itheima02;
//妹子类
public class MeiZi {
private String name = "佳华MM";
private int age = 18;
@Override
public String toString() {
return "MeiZi{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//无参无返回值方法
private void say(){
System.out.println("say无参无返回值");
}
//有参有返回值方法
private String eat(int x,int y){
System.out.println("eat有参有返回值");
return "值:"+x+y;
}
}
B. 访问私有成员变量
//想要访问 私有成员变量 age 多大,并且把 age修改一下
public static void main(String[] args) throws Exception{
//【0】 (准备工作)获取到字节码的对象,并且创建 MeiZi的对象
Class<?> clazz = Class.forName("com.itheima02.MeiZi");
Object o = clazz.newInstance();
System.out.println("o = " + o); //o = MeiZi{name='佳华MM', age=18}
//【1】通过字节码获取 成员变量 Field
Field ageField = clazz.getDeclaredField("age");
//【2】暴力访问,强行摸
ageField.setAccessible(true);
//【3】修改值(参数1:对象,参数2:需要修改的值)
ageField.set(o,38);
//【4】查看值
Object age = ageField.get(o);
System.out.println("age = " + age); //age = 38
System.out.println("o = " + o);//o = MeiZi{name='佳华MM', age=38}
}
C. 访问私有成员方法
//想要访问 私有成员成员方法,并且调用
public static void main(String[] args) throws Exception{
//【0】 (准备工作)获取到字节码的对象,并且创建 MeiZi的对象
Class<?> clazz = Class.forName("com.itheima02.MeiZi");
Object o = clazz.newInstance();
//【1】通过字节码对象,获取方法的对象 Method
Method method01 = clazz.getDeclaredMethod("say");
//【2】设置暴力访问
method01.setAccessible(true);
//【3】调用方法
//参数1是 对象,上面的o.
method01.invoke(o); //say无参无返回值
//===========================
//【1】通过字节码对象,获取方法的对象 Method
Method method02 = clazz.getDeclaredMethod("eat",int.class,int.class);
//【2】设置暴力访问
method02.setAccessible(true);
//【3】调用方法
//参数1是 对象,上面的o.
Object fanhuizhi = method02.invoke(o, 66, 88);//eat有参有返回值
System.out.println("fanhuizhi = " + fanhuizhi);//fanhuizhi = 值:6688
}
第三章 注解
1、注解的概念
A.注释: 给程序员看的
B.注解: 给Java程序看的
2、注解的作用
A.编写文档. javadoc java类
B.检查代码正确性 例如@Override检查是否正确覆盖重写
C.自定义注解,反射之后,设计Java框架
3、系统提供好的注解
A. @Override 检查是否是正确的覆盖重写
B. @FunctionalInterface 检查是否是正确的函数式接口
C. @Deprecated 检查标注的内容是否已经过时了
D. @SuppressWarnings("all") 压制所有的警告信息(防止处女座的)
4、自定义注解
A.格式:
public @interface 注解名称{ ... }
B.本质是一个接口
public interface 注解名称 extends Annotation{ .... }
C.反编译的操作
在cmd控制台当中 javap 类名称.class
5、注解的属性
注解的属性: 在本质为接口的注解里面,定义的抽象方法,我们称之为"属性"。定义注解的时候 变量赋值的格式很类似。
基本数据类型
String
枚举 (一堆常量的在一起)可以列举出来的
注解
以上类型的数组
注解属性的注意事项:
- 如果注解的属性名称是value , 并且只有它一个属性的时候,可以省略 value = 不写
- 如果注解的属性当中存在数组,并且数组的值,只有一个情况下,可以省略大括号不写
- 如果注解的属性,后面跟着 default 的关键字和值,可以省略赋值的操作
6、元注解(注解的注解)
A. @Target:描述注解能够作用的位置(使用频率高)
ElementType取值:
TYPE:可以作用于类上
METHOD:可以作用于方法上
FIELD:可以作用于成员变量上
B. @Retention:描述注解被保留的阶段(使用频率高)
@Retention(RetentionPolicy.RUNTIME):
当前被描述的注解,会保留到class字节码文件中,并被JVM读取到
C. @Documented:描述注解是否被抽取到api文档中
D. @Inherited:描述注解是否被子类继承
7、解析注解
A. 需要操作的类
package com.itheima04;
public class Car {
public void pao(){
System.out.println("汽车跑...");
}
}
B. 自定义注解
//自定义的注解
@Target(ElementType.TYPE) //注解只能加在类上
@Retention(RetentionPolicy.RUNTIME) //在运行时
public @interface MyZhuJie {
String className();
String methodName();
}
C.解析自定义注解
@MyZhuJie(className="com.itheima04.Car",methodName = "pao")
public class Test {
public static void main(String[] args) {
//[1]采用当前字节的对象,获取注解的对象,参数是 字节码对象.class
MyZhuJie zhujie = Test.class.getAnnotation(MyZhuJie.class);
//[2]调用成员方法,抽象方法
String cname = zhujie.className();
String mname = zhujie.methodName();
//====================
//打印输出结果
System.out.println("cname = " + cname); //cname = com.itheima04.Car
System.out.println("mname = " + mname); //mname = pao
}
}
8、自定义注解的使用
A.定义注解
B.添加注解
C.解析注解