单元测试
黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值
白盒测试:需要写代码.关注程序具体的执行过程
Junit测试:白盒测试
步骤:
-
定义一个测试类(测试用例)
建议:
测试类名:被测试类名Test
包名:xxx.xx.xx.test
-
定义测试方法:可独立运行
建议:
方法名:test测试方法名
返回值:void
参数列表:空参数
-
给方法加 @Test
-
导入Junit的依赖
断言:Assert.function(except,res)
public class ClassNameTest{
// 所有测试方法执行前都会执行该方法
@Before
public void init(){}
// 所有测试方法执行玩都会执行该方法
@After
public void close(){}
@Test
public void test1(){}
@Test
public void test2(){}
}
反射
框架设计的灵魂
框架:半成品软件. 可以在框架的基础上进行软件开发,简化代码
反射: 将类的各个组成部分封装为其他对象
好处:
1. 在程序的运行过程中,操作这些对象
2. 可以解耦,提高程序的可扩展性
获取Class对象的方式:
1. Class.forName("全类民"): 从字节码加载到内存,返回对象 (编译后)
1. 多用于配置文件,将类名定义在配置文件中.读取文件,加载类
2. 类名.class : 通过类名的属性class获取 (加载完成后)
1. 多用于参数传递
3. 对象.getClass() : 使用Object类的getClass方法 (创建对象后)
1. 多用于对象获取字节码
结论:
同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次.
class对象功能
获取功能:
-
获取成员变量们
Field[] getFields()
Field getField(String name)
Field[] getDeclaredFields()
Field getDeclaredFields(String name)
package demo2.reflect; import demo2.domain.Person; import java.lang.reflect.Field; public class ReflectDemo1 { /** 获取Class对象的方式: 1. Class.forName("全类民"): 从字节码加载到内存,返回对象 (编译后) 2. 类名.class : 通过类名的属性class获取 (加载完成后) 3. 对象.getClass() : 使用Object类的getClass方法 (创建对象后) */ public static void main(String[] args) throws Exception { // 0.获取Person的Class对象 Class<Person> personClass = Person.class; // 1.获取所有 Public 的成员变量 Field[] fields = personClass.getFields(); for (Field field : fields) { System.out.println(field);//public java.lang.String demo2.domain.Person.a } System.out.println("-----------"); // 2.获取名字为 a 的 Public 的成员变量 Field a = personClass.getField("a"); Person person = new Person(); // 3.获取 a 变量的值 Object o = a.get(person); System.out.println(o);//null // 4.设置 a 变量的值 a.set(person,"a3"); System.out.println(person);//Person{name='null', age=null, a='a3', b='null', c='null', d='null'} // 1. 获取所有 成员变量 Field[] declaredFields = personClass.getDeclaredFields(); for (Field field : declaredFields) { System.out.println(field); } // 2. 获取指定名字的 成员变量 Field d = personClass.getDeclaredField("d"); // 3. 获取 私有变量 d 的值 // d.get(person); // 报错 // 如果设置或访问私有变量,需要暴力反射 d.setAccessible(true); Object o1 = d.get(person); System.out.println(o1); // 4. 设置 变量的值同上 d.set(person,"d3"); System.out.println(person);//Person{name='null', age=null, a='a3', b='null', c='null', d='d3'} } }
-
获取构造方法们
- 类似
-
获取成员方法们
- 类似
-
获取类名:
getName()
构造方法返回的Constructor 方法:
class Constructor
// 创建对象
T newInstance(Object... initargs)
// 创建空参对象也可使用
ClassObject.newInstance()
需求:写一个框架,不能改变该类的任何代码,可以创建任意类的对象,并且执行其中任意方法
实现:
1. 配置文件
2. 反射
package demo2.reflect;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class ReflectDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
Properties properties = new Properties();
ClassLoader classLoader = ReflectDemo.class.getClassLoader();
InputStream resourceAsStream = classLoader.getResourceAsStream("pro.properties");
properties.load(resourceAsStream);
String className = properties.getProperty("className");
String methodName = properties.getProperty("methodName");
// 获取 class对象
Class aClass = Class.forName(className);
// 获取 方法
Method method = aClass.getMethod(methodName);
// 创建实例对象
Object o = aClass.newInstance();
method.invoke(o);
}
}
注解
注释:用文字描述程序,给程序员看的
概念: 说明程序,给计算机看的
概念描述:
1. jdk1.5之后的特性
2. 说明程序的
3. 使用注解: `@注解名称`
作用分类:
- 编写文档: 生成javadoc文档
- 代码分析
- 编译检查: 例如:@Override
JDK中预定义的一些注解
@Override
检测被注解的方法是否继承自父类
@Deprecated
该注解标注的内容,表示已过时
@SuppressWarnings
压制警告
- 一般传递参数"all" @SupperssWarnings("all")
自定义注解
格式:
元注解
public @interface 注解名称{
}
本质: 注解本质就是一个接口,该接口默认继承Annocation接口
public interface annocationname extends java.lang.annotation.Annotation{}
属性:接口中的抽象方法
1. 要求属性的返回值类型:
1. 基本数据类型
2. String
3. 枚举
4. 注解
5. 以上类型的数组
2. 定义的属性在使用是需要被赋值
1. 如果定义属性时,使用default关键字给属性赋默认值
2. 如果只有一个属性,属性名为value,则可以直接写值
3. 数组赋值时,值使用{}包裹,如果只有一个值,{}可省略
4. 注解类型赋值使用@注解名
元注解: 用于描述注解的注解
@Target: 描述注解能够作用的位置
属性为ElementType[] value
ElemenType为枚举:
TYPE 类
METHOD 方法
FIELD 变量
@Retention: 描述注解被保留的阶段
属性为RententionPolicy value
RententionPolicy为枚举:
RUNTIME 保留到class字节码文件中,并被jvm读取到
@Documented:描述注解是否被抽取到api文档中
@:描述注解是否能被继承
使用注解(获取注解中定义的值)
-
使用注解取代配置文件来配置程序
-
测试框架
小结:
- 以后大多数时候,我们都会使用注解,而不是自定义注解
- 注解给编译器用,给解析程序用
- 注解不是程序的一部分,可以理解为一个标签