Junit单元测试:
测试分类:
1.黑盒测试:不需要写代码,给输入值,看程序能否输出期望的值
2.白盒测试:需要写代码。关注程序具体的执行流程。
Junit使用:白盒测试
使用步骤:
1.定义一个测试类(测试用例)
建议:测试类名:被测试的类名Test
包名:xxx.xxx.xx.test
2.定义测试方法:可以独立运行
建议:方法名:test测试的方法名
返回值:void
参数列表:空参
3.给方法加@Test注解
4.导入Junit的依赖文件
判定结果:
红色:失败
绿色:成功
一般我们会使用断言操作处理结果:Assert.assertEquals(期望的结果,运算的结果);
补充:
@Before:修饰的方法会在测试方法之前被自动执行
@After:修饰的方法会在测试方法执行之后自动被执行
/*
* 计算器类
* */
public class Calculator {
//加法
public int add(int a,int b){
//int i=3/0;//ArithmeticException: / by zero
return a+b;
}
//减法
public int sub(int a,int b){
return a-b;
}
}
public class CalculatorTest {
/*
* 初始化方法:
* 用于资源申请,所有测试方法在执行之前都会执行该方法
* */
@Before
public void init(){
System.out.println("init....");
}
/*
* 释放资源的方法:
* 在所有测试方法执行完后,都会自动执行该方法
* */
@After
public void close(){
System.out.println("close.....");
}
/*
* 测试add方法
* */
@Test
public void testAdd(){
//System.out.println("我被执行了");
//创建计算器对象
//调用add方法
Calculator c=new Calculator();
int add = c.add(1, 2);
System.out.println(add);
//断言,断言结果为3
Assert.assertEquals(3,add);
}
@Test
public void testSub(){
Calculator c=new Calculator();
int sub = c.sub(2, 1);
Assert.assertEquals(1,sub);
}
}
反射:框架设计的灵魂
框架:半成品软件。可以在框架的基础上进行软件的开发,简化编码
反射概念:将类的各个组成部分封装为其他对象,这就是反射机制。
好处:
1.可以在程序的运行过程中,操作这些对象。
2.可以解耦,提高程序的可扩展性。
Java代码在计算机中经历的阶段:三个阶段
Source源代码阶段-》Class类对象阶段-》Runtime运行时阶段
获取Class对象的方式:
1.Source源代码阶段:
Class.forName("全类名"):将字节码文件加载进内存,返回class对象
多用于配置文件,将类名定义在配置文件中,读取文件,加载类
2.Class类对象阶段:
类名.class:通过类名的属性class获取
多用于参数传递
3.Runtime运行时阶段:
对象.getClass():getClass()方法在Object类中定义着。
多用于对象的获取字节码的方式
public class ReflectDemo1 {
/*
获取Class对象的方式:
1.Class.forName("全类名"):将字节码文件加载进内存,返回class对象
2.类名.class:通过类名的属性class获取
3.对象.getClass():getClass()方法在Object类中定义着。
*/
public static void main(String[] args) throws Exception {
//1.Class.forName("全类名")
Class cls1 = Class.forName("domain.Person");
System.out.println(cls1);
//2.类名.class
Class cls2 = Person.class;
System.out.println(cls2);
//3.对象.getClass()
Person p=new Person();
Class cls3 = p.getClass();
System.out.println(cls3);
//==比较三个对象
System.out.println(cls1==cls2);//true
System.out.println(cls1==cls3);//true
//结论:同一个字节码文件,在一次程序运行过程中,只会被加载一次,不论被哪种方式获取的Class对象都是同一个
Class c = Student.class;
System.out.println(c==cls1);//false
}
}
Class对象功能概述:
Class对象功能:
获取功能:
1.获取成员变量们
Field[] getFields():获取所有public修饰的成员变量
Field getField(String name)
Field[] getDeclareFields()
Field[] getDeclareFields(String name)
2.获取构造方法们
Constructor<?>[] getConstructors()
Constructor<T> getConstructors(类<?>... parameterTypes )
Constructor<?>[] getDeclaredConstructors()
Constructor<T> getDeclaredConstructors(类<?>... parameterTypes )
3.获取成员方法们
Method[] getMethods()
Method getMethod(String name,类<?>...parameterTypes)
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name,类<?>...parameterTypes)
4.获取类名
String getName()
Field:成员变量
操作:
1.设置值 void set(Object obj,Object value)
2.获取值 get(Object obj)
3.忽略访问权限修饰符的安全检查 setAccessible(true):暴力反射
public class Reflect02 {
public static void main(String[] args) throws Exception {
//1.获取Person的Class对象
Class<Person> personClass = Person.class;
/*1.获取成员变量们
Field[] getFields():获取所有public修饰的成员变量
Field getField(String name)
Field[] getDeclareFields()
Field[] getDeclareFields(String name)
*/
//2.Field[] getFields()
Field[] fields = personClass.getFields();
for (Field f : fields) {
System.out.println(f);
}
System.out.println("=============");
//3.Field getField(String name)
Field a = personClass.getField("a");
//获取成员变量a的值
Person p=new Person();
Object value = a.get(p);
System.out.println(value);
//设置a的值
a.set(p,"张三");
System.out.println(p);
System.out.println("==========");
//4.Field[] getDeclareFields():获取所有的成员变量,不考虑修饰符
Field[] declaredFields = personClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
//5.Field[] getDeclareFields(String name)
Field d = personClass.getDeclaredField("d");
//忽略访问的权限修饰符的安全检查
d.setAccessible(true);//暴力反射
Object value2 = d.get(p);
System.out.println(value2);
}
}
Constructor:构造方法
创建对象:T newInstance(Object...initargs)
如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
public class Reflect01 { public static void main(String[] args) throws Exception { //获取Person的Class对象 Class personClass = Person.class; /* * 获取构造方法们 Constructor<?>[] getConstructors() Constructor<T> getConstructors(类<?>... parameterTypes ) Constructor<?>[] getDeclaredConstructors() Constructor<T> getDeclaredConstructors(类<?>... parameterTypes ) */ //Constructor<T> getConstructors(类<?>... parameterTypes ) Constructor constructor = personClass.getConstructor(String.class, int.class); System.out.println(constructor); //创建对象 Object person = constructor.newInstance("张三", 23); System.out.println(person); System.out.println("=========="); Constructor constructor1 = personClass.getConstructor(); System.out.println(constructor); //创建对象 Object person1 = constructor1.newInstance(); System.out.println(person1); Object o = personClass.newInstance(); System.out.println(o); } }
获取Method:
Method:方法对象
执行方法:Object invoke(Object obj,Object...args)
获取方法的名称:String getName()
public class Reflect04 { public static void main(String[] args) throws Exception { Class personClass = Person.class; /* * 3.获取成员方法们 Method[] getMethods() Method getMethod(String name,类<?>...parameterTypes) Method[] getDeclaredMethods() Method getDeclaredMethod(String name,类<?>...parameterTypes) */ //获取指定名称的方法 Method eat_method= personClass.getMethod("eat"); Person p=new Person(); eat_method.invoke(p); Method eat_method2 = personClass.getMethod("eat", String.class); //执行方法 eat_method2.invoke(p,"饭"); System.out.println("======="); //获取所有public修饰的方法 Method[] methods = personClass.getMethods(); for (Method method : methods) { System.out.println(method); //method.setAccessible(true); String name = method.getName(); System.out.println(name); } //获取类名 String className = personClass.getName(); System.out.println(className); } }
反射案例:
需求:写一个“框架”,可以帮我们创建任意类的对象,并且执行其中任意方法。
实现:
1.配置文件
2.反射
步骤:
1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中
2.在程序中加载读取配置文件
3.使用反射技术来加载类文件进内存
4.创建对象
5.获取方法对象
6.执行方法
配置文件pro.properties:
className=domain.Person methodName=eat /* * 框架类 * */ public class ReflectTest { public static void main(String[] args) throws Exception { //可以创建任意类的对象,可以执行任意方法 /* * 前提:不能改变该类的任何代码。可以创建任意类的对象,可以执行任意方法 * */ /*Person p=new Person(); p.eat();*/ /*Student stu=new Student(); stu.sleep();*/ //1.加载配置文件 //1.1创建Properties对象 Properties pro=new Properties(); //1.2加载配置文件,转换为一个集合 //1.2.1获取class目录下的配置文件 ClassLoader classLoader = ReflectTest.class.getClassLoader(); InputStream is = classLoader.getResourceAsStream("pro.properties"); pro.load(is); //2.获取配置文件中定义的数据 String className = pro.getProperty("className"); String methodName = pro.getProperty("methodName"); //3.加载该类进内存 Class cls = Class.forName(className); //4.创建对象 Object obj = cls.newInstance(); //5.获取方法对象 Method method = cls.getMethod(methodName); //6.执行方法 method.invoke(obj); } }