Java基础回顾——反射
2021/5/21 12:29:46
本文主要是介绍Java基础回顾——反射,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录- 基础加强
- Junit单元测试
- 测试分类
- Junit使用:白盒测试
- 步骤
- 反射:框架设计的灵魂
- 获取Class对象的方式
- class对象功能:
- 1.获取功能:
- class对象功能:
- 反射的案例
- 需求:
- 实现:
- 步骤:
- Junit单元测试
基础加强
Junit单元测试
测试分类
黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值。
白盒测试:需要写代码的。关注程序具体的执行流程。
Junit使用:白盒测试
步骤
- 定义一个测试类(测试用例)
建议∶
测试类名:被测试的类名Test calculatorTest
包名∶xxx.xxx.xx.test com.niu.test - 定义测试方法:可以独立运行
建议︰
方法名: test测试的方法名 testAdd()
返回值: void
参数列表:空参 - 给方法加@Test
- 导入junit依赖环境
判定结果︰
红色:失败
绿色:成功
一般我们会使用断言操作来处理结果
Assert.assertEquals(期望得结果,运算的结果);
补充:
@Before
初始化方法:用于资源申请,所有测试方法在执行之前都会先执行该方法
@After
释放资源方法:在所有测试方法执行完后,都会自动执行该方法
个人理解:以前咋们测试程序是否正常都是用main方法,在主函数里调用方法来验证是否运行成功,这样会有很多缺点,比如:
- 为了让多个方法之间不会互相产生影响,每次测试一个方法之前要把测试的其他方法注释掉;
- 用来测试的程序和要测试的方法程序放在同一个目录下,比较混乱,不好管理;
- 等等不方便的地方。
所以我们要学注解@Test
import org.junit.Assert; import org.junit.Test; public class CalculatorTest { @Test public void testAdd(){ Calculator c = new Calculator(); int add = c.add(1, 22); System.out.println(add); //断言 我断言 } @Test public void testSub(){ Calculator c = new Calculator(); int sub = c.sub(2, 1); //断言,括号里的参数,前面一个参数是期望值,后面一个参数是真实得到的值 //如果二者一样 就说明程序没什么问题了,运行结果没有任何异常,也没有返回值。 Assert.assertEquals(1,sub); } }
注解:@Before和@After
import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class CalculatorTest { /** * 初始化方法: * 用于资源申请,所有测试方法在执行之前都会先执行该方法 */ @Before public void init(){ System.out.println("init..."); } /** * 释放资源方法: * 在所有测试方法执行完后,都会自动执行该方法 */ @After public void close(){ System.out.println("close..."); } @Test public void testAdd(){ Calculator c = new Calculator(); int add = c.add(1, 22); System.out.println(add); //断言 我断言 } @Test public void testSub(){ Calculator c = new Calculator(); int sub = c.sub(2, 1); //断言,括号里的参数,前面一个参数是期望值,后面一个参数是真实得到的值 //如果二者一样 就说明程序没什么问题了,运行结果没有任何异常,也没有返回值。 Assert.assertEquals(1,sub); } }
反射:框架设计的灵魂
框架:半成品软件。可以在框架基础上进行软件开发,简化代码。
反射:将类的各个组成部分封装成其他对象,这就是反射机制
使用反射的好处:
- 在程序的运行过程中,操作这些对象
- 可以解耦,来提高程序的可扩展性。
获取Class对象的方式
- Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
多用于配罩i文件,将类名定义在配置i文件中。读取文件,加载类 - 类名.Class:通过类名的属性class来获取
多用于参数的传递 - 对象.getClass :getClass()方法在Object类中定义着
多用于对象的获取字节码的方式
结论∶
同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取class对象都同一个。
class对象功能:
1.获取功能:
-
获取成员变们
Field[] getFields() Field getField(string name) Field[getDeclaredFields() Field getDeclaredField(string name)
-
获取构造方法们
Constructor<?>[] getConstructors( Constructor<T> getConstructor(类<?>... parameterTypes) Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)* Constructor<?>[] getDeclaredConstructors()
-
获取成员方法们∶
Method[]getMethods( Method getMethod(string name,类<?>... parameterTypes) Method[] getDeclaredMethods() Method getDeclaredMethod(string name,类<?>... parameterTypes)
-
获取类名
String getName()
暴力反射:setAccessible();//忽略访问权限修饰符安全检查
反射的案例
需求:
写一个"框架"【类】,在不改变该类的任意代码的前提下,可以帮助我们创建任意类的对象,并执行其中任意方法
实现:
1.配置文件
2.反射
步骤:
1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中
2.在程序中加载读取配置文件
3.使用反射技术,来加载类文件进内存,并创建对象,并执行方法
代码:
Person.java
package domain; public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } 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; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } public void eat(){ System.out.println("eat..."); } }
Student.java
package domain; public class Student { public void sleep(){ System.out.println("sleep..."); } }
a.properties
className=domain.Student methodName=sleep
ReflectTest.java
package domain; import java.io.InputStream; import java.lang.reflect.Method; import java.util.Properties; public class ReflectTest { public static void main(String[] args) throws Exception { //可以创建任意类的对象,可以执行任意方法 /* 可以称为框架的前提:不能改变该类的任意代码,可以创建任意类的对象,可以执行任意方法 */ /*Person p = new Person(); p.eat();*/ /*Student student = new Student(); student.sleep();*/ /* 1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中 2.在程序中加载读取配置文件 3.使用反射技术,来加载类文件进内存,并创建对象,并执行方法 */ //1.加载配置文件 //1-1创建Properties对象 Properties pro = new Properties(); //1.2加载配置文件,转换为一个集合(双链Map集合,因为Properties是Map的一个子类) //1.3获取文件路径(class目录下的配置文件) ClassLoader cl = ReflectTest.class.getClassLoader();//获取到了类加载器 InputStream ras = cl.getResourceAsStream("a.properties");//得到了a.properties文件的字节流 pro.load(ras); //2.获取配置文件a.properties中定义的数据("className"和"methodName") String cN = pro.getProperty("className"); String mN = pro.getProperty("methodName"); //3.加载该类进内存 Class cls = Class.forName(cN); //4.创建对象 Object obj = cls.newInstance(); //5.获取方法对象 Method method = cls.getMethod(mN); //6.执行方法 method.invoke(obj); } }
改写配置文件a.properties文件之前
改写配置文件a.properties文件之后
a.properties
className=domain.Person methodName=eat
个人总结:用了反射之后,我们只需要更改配置文件,就可以让程序完成不同的工作,不用去改源代码,这样代码也更好管理~
这篇关于Java基础回顾——反射的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-26大厂数据结构与算法教程:入门级详解
- 2024-12-26大厂算法与数据结构教程:新手入门指南
- 2024-12-26Python编程入门指南
- 2024-12-26数据结构高级教程:新手入门及初级提升指南
- 2024-12-26并查集入门教程:从零开始学会并查集
- 2024-12-26大厂数据结构与算法入门指南
- 2024-12-26大厂算法与数据结构入门教程
- 2024-12-26二叉树入门教程:轻松掌握基础概念与操作
- 2024-12-26初学者指南:轻松掌握链表
- 2024-12-26平衡树入门教程:轻松理解与应用