Junit,反射

Junit

1.测试的分类:

  • 黑盒测试 : 不需要写代码,给输入值,看程序是否能够输出期望的值。
  • 白盒测试 : 需要进行代码的编写,关注的是程序的具体流程.

2.使用步骤(方法类的命名可以参考阿里巴巴开发手册):

* 步骤:
1. 定义一个测试类(测试用例)
* 建议:
* 测试类名:被测试的类名Test
* 包名:xxx.xxx.xx.test 2. 定义测试方法:可以独立运行
* 建议:
* 方法名:test测试的方法名 testAdd()
* 返回值:void
* 参数列表:空参 3. 给方法加@Test
4. 导入junit依赖环境 * 判定结果:
* 红色:失败
* 绿色:成功
* 一般我们会使用断言操作来处理结果
* Assert.assertEquals(期望的结果,运算的结果); * 补充:
* @Before:
* 修饰的方法会在测试方法之前被自动执行
* @After:
* 修饰的方法会在测试方法执行之后自动被执行 // 举个例子
public class Calculator { /**
* 加法运算
* @param a 加数
* @param b 被加数
* @return 和
*/
public int add(int a,int b){
return a + b;
} /**
* 减法运算
* @param a 减数
* @param b 被减数
* @return 差值
*/
public int sub(int a,int b){
return a - b;
}
} // 测试类的创建
package com.wzlove.test; import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test; /**
* @author 王智
* @date 2018/7/31
* @描述 测试类
*/ public class CalculatorTest { Calculator cal; /**
* 初始化
*/
@Before
public void init(){
// 初始化对象
cal = new Calculator();
System.out.println("init==================================================");
} /**
* 测试加法运算
*/
@Test
public void testAdd(){
// 调用方法
int result = cal.add(10, 10);
// 断言
Assert.assertEquals(20,result);
} /**
* 测试减法运算
*/
@Test
public void testSub(){
// 调用方法
int result = cal.sub(10, 10);
// 断言
Assert.assertEquals(0,result);
} @After
public void end(){
System.out.printf("end========================================");
}
}

反射 : 框架的设计灵魂

  • 框架:半成品软件。可以在框架的基础上进行软件开发,简化编码

  • 反射:将类的各个组成部分封装为其他对象,这就是反射机制

    • 好处:

      1. 可以在程序运行过程中,操作这些对象。
      2. 可以解耦,提高程序的可扩展性。
  • 获取Class对象的方式:

    1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象

      • 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
    2. 类名.class:通过类名的属性class获取
      • 多用于参数的传递
    3. 对象.getClass():getClass()方法在Object类中定义着。
      • 多用于对象的获取字节码的方式
    • 结论:

      同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。

    package com.wzlove.reflect;

      /**
    * @author 王智
    * @date 2018/7/31
    * @描述 获取字节码对象的三种方式
    */
    public class GetClassObject { public static void main(String[] args) throws Exception {
    // 第一种: 使用全类名进行获取
    Class<?> aClass = Class.forName("com.wzlove.reflect.GetClassObject");
    System.out.println(aClass);
    // 第二种: 使用类名的属性获取
    Class aClass1 = GetClassObject.class;
    System.out.println(aClass1);
    // 第三种: 使用类的方法进行获取
    Class<?> aClass2 = new GetClassObject().getClass();
    System.out.println(aClass2); System.out.println(aClass == aClass1);
    System.out.println(aClass == aClass2);
    }
    }
  • Class对象功能:

    • 获取功能:

      1. 获取成员变量们

        • Field[] getFields() :获取所有public修饰的成员变量

        • Field getField(String name) 获取指定名称的 public修饰的成员变量

        • Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符

        • Field getDeclaredField(String name)

      2. 获取构造方法们

        • Constructor<?>[] getConstructors()

        • Constructor getConstructor(Class<?>... parameterTypes)

        • Constructor getDeclaredConstructor(Class<?>... parameterTypes)

        • Constructor<?>[] getDeclaredConstructors()

      3. 获取成员方法们:

        • Method[] getMethods()

        • Method getMethod(String name, Class<?>... parameterTypes)

        • Method[] getDeclaredMethods()

        • Method getDeclaredMethod(String name, Class<?>... parameterTypes)

      4. 获取全类名

        • String getName()
  • Field:成员变量

    • 操作:

      1. 设置值

        • void set(Object obj, Object value)
      2. 获取值

        • get(Object obj)
      3. 忽略访问权限修饰符的安全检查

        • setAccessible(true):暴力反射

    // 下面的例子全部使用Student类

    package com.wzlove.reflect;

      /**
    * @author 王智
    * @date 2018/7/31
    * @描述
    */
    public class Student { private String name; private int age; public String sex; @Override
    public String toString() {
    return "Student{" +
    "name='" + name + '\'' +
    ", age=" + age +
    ", sex='" + sex + '\'' +
    '}';
    } public String getName() {
    return name;
    } public void setName(String name) {
    this.name = name;
    } public int getAge() {
    return age;
    } public void setAge(int age) {
    this.age = age;
    } public String getSex() {
    return sex;
    } public void setSex(String sex) {
    this.sex = sex;
    } public Student(String name, int age, String sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    } public Student() {
    }
    } package com.wzlove.reflect; import java.lang.reflect.Field; /**
    * @author 王智
    * @date 2018/7/31
    * @描述 利用反射获取对象的成员变量
    */
    public class GetFieldDemo { public static void main(String[] args) throws Exception {
    // 利用反射获取公有成员变量的步骤
    // 1. 获取反射对象(3种方法)
    Class aClass = Student.class;
    // 2. 获取成员变量
    Field sex = aClass.getField("sex");
    // 3. 使用Field的方法设置值(需要创建对象)
    Student stu = new Student();
    sex.set(stu,"男");
    // 4. 使用Field的方法获取值
    System.out.println(sex.get(stu)); // 获取所有成员变量
    // 1. 获取反射对象(3种方法)
    Class aClass1 = Student.class;
    // 2. 获取成员变量
    Field name = aClass1.getDeclaredField("name");
    // 3. 使用Field的方法设置值(需要创建对象)
    Student stu1 = new Student();
    // 4. 再使用私有变量的时候会报错,所以要跳过检测,也成为暴力反射
    name.setAccessible(true);
    name.set(stu1,"王智");
    // 6. 使用Field的方法获取值
    System.out.println(name.get(stu1));
    } }
  • Constructor:构造方法

    • 创建对象:

      1. T newInstance(Object... initargs)

      2. 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

    package com.wzlove.reflect;

      import java.lang.reflect.Constructor;
    
      /**
    * @author
    * @date 2018/7/31
    * @描述 利用反射获取对象的构造方法
    */
    public class GetConstructDemo { public static void main(String[] args) throws Exception {
    // 利用反射获取公有成员变量的步骤
    // 1. 获取反射对象(3种方法)
    Class aClass = Student.class;
    // 2. 使用方法获取构造方法的对象
    Constructor constructor = aClass.getConstructor(String.class, int.class, String.class);
    // 3. 使用Constructor对象初始化对象
    Object obj = constructor.newInstance("张三", 23, "男");
    // 测试输出结果
    System.out.println(obj);
    System.out.println("==================================="); // 无参构造的方法
    // 1. 获取反射对象(3种方法)
    Class aClass1 = Student.class;
    // 2. 使用方法获取构造方法的对象
    Constructor constructor1 = aClass1.getConstructor();
    // 3. 使用Constructor初始化对象
    Object obj1 = constructor1.newInstance();
    // 测试输出结果
    System.out.println(obj1); // 还有个简化写法,仅仅适用于无参构造,但是我使用JDK10已经不推荐使用了
    Object obj2 = aClass1.newInstance();
    System.out.println(obj2); // getDeclaredConstructor方法也是获取私有的构造方法,就不演示了
    } }
  • Method:方法对象

    • 执行方法:

      • Object invoke(Object obj, Object... args)
    • 获取方法名称:

      • String getName:获取方法名

首先在Student中添加两个方法

public void eat(){
System.out.println("eat..............");
} public int add(int a, int b){
return a + b;
} package com.wzlove.reflect; import java.lang.reflect.Method; /**
* @author 王智
* @date 2018/7/31
* @描述 反射执行方法
*/
public class GetMethodDemo { public static void main(String[] args) throws Exception {
// 无参无返回值的方法
// 1. 创建字节码对象
Class aClass = Student.class;
// 2. 创建方法的对象
Method eat = aClass.getMethod("eat");
// 3. 执行方法
Student stu = new Student();
eat.invoke(stu); // 有参有返回值的方法
// 1. 创建字节码对象
Class aClass1 = Student.class;
// 2. 创建方法的对象
Method add = aClass1.getMethod("add", int.class,int.class);
// 3. 执行方法
Student stu1 = new Student();
Object sum = add.invoke(stu1, 10, 10);
System.out.println("和为" + sum);
System.out.println("======================================================");
// 获取该类所有的方法(这里获取的不仅仅是自己定义的方法,还有从父类继承来的方法)
Method[] methods = aClass1.getMethods();
for (Method method : methods) {
System.out.println(method);
System.out.println(method.getName());
}
System.out.println("======================================================"); // 获取类名
System.out.println(aClass1.getName());
// getDeclaredMethod也是同样的道理
}
}

以上就是反射的简单使用了.举个简单例子,当然这个例子并不完善,将就看

package com.wzlove.reflect;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Properties; /**
* @author
* @date 2018/7/31
* @描述
* * 案例:
* * 需求:写一个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,
* 并且执行其中任意方法
* * 实现:
* 1. 配置文件
* 2. 反射
* * 步骤:
* 1. 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
* 2. 在程序中加载读取配置文件
* 3. 使用反射技术来加载类文件进内存
* 4. 创建对象
* 5. 执行方法
*/
public class ReflectDemo { public static void main(String[] args) throws Exception {
// 创建本类的字节码对象
Class aClass = ReflectDemo.class;
// 获取类加载器对象
ClassLoader classLoader = aClass.getClassLoader();
// 加载配置文件,返回字节流对象
InputStream resourceAsStream = classLoader.getResourceAsStream("pro.properties"); // 读取配置文件
// 创建Properties对象
Properties properties = new Properties();
properties.load(resourceAsStream); // 反射的使用
Object className = properties.getProperty("className");
Object methodName = properties.getProperty("methodName");
// 使用反射创建对象
Class aClass1 = Class.forName((String) className);
Constructor constructor = aClass1.getConstructor();
Object obj = constructor.newInstance();
// 利用反射获取方法
Method method = aClass1.getMethod((String) methodName);
// 使用反射执行方法
method.invoke(obj); } }

Java之Junit和反射的更多相关文章

  1. 5.java动态代理、反射

    1.java动态代理.反射(IDEA导入JUnit4) 1.1.反射 通过反射的方式可以获取class对象中的属性.方法.构造函数等 1.2.反射代码 import java.io.Serializa ...

  2. Java类加载和类反射回顾

    今天学习Spring,突然想重新复习一下Java类加载和类反射的.巩固一下底层原理.部分参考了李刚老师的<疯狂Java讲义>和陈雄华.林开雄的<Spring3.x企业应用开发实战&g ...

  3. 【GoLang】golang 如何像Java 一样通过类名反射对象?

    结论: golang不支持解析string然后执行. golang的反射机制只能存在于已经存在的对象上面. 不知道后续的版本有没有规划,现在只能先加载注册,然后实现类似Java工厂模式的反射. 代码示 ...

  4. java学习:用反射构造bean

    先贴一些反射的基本知识:-------------------------------------------------------------------- 一.什么是反射:反射的概念是由Smit ...

  5. 反射那些事儿——Java动态装载和反射技术

    一直以来反射都是只闻其声,却无法将之使用,近日尽心下来学习下,发现了很多精妙之处. Java动态装载和反射技术 一.类的动态装载 1.Java代码编译和执行的整个过程包含了以下三个重要的机制: ● J ...

  6. Java 工具 JUnit单元测试

    Java 工具 JUnit单元测试 @author ixenos 1.1.   JUnit单元测试框架的基本使用 一.搭建环境: 导入junit.jar包(junit4) 二.写测试类: 0,一般一个 ...

  7. Java基础学习笔记二十三 Java核心语法之反射

    类加载器 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,链接,初始化三步来实现对这个类进行初始化. 加载就是指将class文件读入内存,并为之创建一个Class对象.任 ...

  8. Java提升篇之反射的原理

    Java提升篇之反射的原理 1.构造方法的反射 import java.lang.reflect.Constructor; public class ReflectConstructor { publ ...

  9. java自动化-junit框架简述

    本人使用的是java的junit框架来组织的自动化测试,故我这边需要简单介绍一下junit框架 首先,建议自行百度一下junit框架,先有一个大概的了解 所谓的接口自动化测试,会对多个接口中每一个接口 ...

随机推荐

  1. 小球下落(Dropping Balls, Uva 679)

    题目描述 有一棵二叉树,最大深度为D,且所有的叶子深度都相同.所有结点从上到下从左到右编号为1,2,3,-,2eD-1.在结点1处放一个小球,它会往下落.每个结点上都有一个开关,初始全部关闭,当每次有 ...

  2. CentOS赋予一个普通用户root权限

    http://www.linuxidc.com/Linux/2012-07/64530.htm

  3. 欢迎来怼--第二十二次Scrum会议

    欢迎来怼--第二十二次Scrum会议 一.小组信息 队名:欢迎来怼 小组成员 队长:田继平 成员:李圆圆,葛美义,王伟东,姜珊,邵朔,阚博文 小组照片 二.开会信息 时间:2017/11/10 17: ...

  4. Task 6.3 场景调研

    1.背景: (1)典型用户:信息1303班王银凤 (2)用户的需求/迫切需要解决的问题:她们宿舍上网一直使用的是外网,一年400的一种“套餐”.这种是按小时计算的,在校的时间平均下来一天可以用7 . ...

  5. 新手学ajax1

       学习的动力是最近想实现servlet向js传值,是html中的js,因为jsp是可以直接调用java 类的,在网上搜索了好久感觉ajax能帮我实现. 以下代码可以实现js向服务器发出一 requ ...

  6. UIPickerView的使用

    简介:UIPickerView是一个选择器控件,它比UIDatePicker更加通用,它可以生成单列的选择器,也可生成多列的选择器,而且开发者完全可以自定义选择项的外观,因此用法非常灵活.UIPick ...

  7. CANOpen的几种操作以及数据

    其实3年前在21ic就准备做这篇文章了,那时,CANOpen也只是刚刚在国内推广,所以几乎没有项目用到.现在有了实际的项目,完全确认了以前移植和测试的代码,所以列举一些CANOpen的底层操作以及数据 ...

  8. Android:java.lang.OutOfMemoryError:GC overhead limit exceeded

    Android编译:java.lang.OutOfMemoryError:GC overhead limit exceeded 百度好多什么JVM啊之类的东西,新手简单粗暴的办法: 1.在的Model ...

  9. Scrum 5.0

    5.0--------------------------------------------------- 1.团队成员完成自己认领的任务. 2.燃尽图:理解.设计并画出本次Sprint的燃尽图的理 ...

  10. java、maven环境搭建

    1.选择[新建系统变量]--弹出"新建系统变量"对话框,在"变量名"文本框输入"JAVA_HOME",在"变量值"文本框 ...