当前位置: 首页 > news >正文

Javase 高级技术 —— 01 反射

本系列为笔者学习Javase的课堂笔记,视频资源为B站黑马程序员出品的《黑马程序员Java+AI智能辅助编程全套视频教程,java零基础入门到大牛一套通关》,章节分布参考视频教程,为同样学习Javase系列课程的同学们提供参考。

01 单元测试

单元测试就是针对最小的功能单元——方法,编写测试代码对其进行正确性测试。

咱们之前是如何进行单元测试的?有啥问题?

  • main方法编写代码,调用其他方法测试
  • 无法实现自动化测试
  • 无法得到测试的报告

Junit单元测试框架可以用来对方法进行测试,其是第三方公司开源出来的。

优点

  • 自动化测试,且各自独立
  • 自动生成测试报告

在这里插入图片描述

在这里插入图片描述

02 反射

反射就是加载类,并允许以编程的方式解剖类中的各种成分,包括成员变量、成员方法、构造器。

在这里插入图片描述

操作步骤

① 加载类,获取类的字节码(class类对象)
在这里插入图片描述

  • Class c1 = 类名.class
  • 调用Class提供方法:public static Class forName(String package);
  • 调用Object提供方法:public Class getclass(); Class c3 = 对象.getClass(0);
package ReflectDemo;public class ReflectDemo {public static void main(String[] args) throws Exception {//目标:认识反射,获取类的Class对象的三种方式//1.类.class [类本身]Class c1 = Student.class;System.out.println(c1);//2.Class.forName [类的全类名]Class c2 = Class.forName("ReflectDemo.Student");System.out.println(c1);//3.对象.getClass() [类本身]Student s = new Student();Class c3 = s.getClass();System.out.println(c3);}
}

② 获取类的构造器(Constructor对象)

③ 获取类的成员变量(Field对象)

④ 获取类的成员方法(Method对象)

ReflectDemo.java

package ReflectDemo;import org.junit.Test;import javax.swing.plaf.metal.MetalTheme;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.MalformedParametersException;
import java.lang.reflect.Method;public class ReflectDemo2 {@Testpublic void getClassInfo() {//目标:获取类的信息(成员变量、成员方法、构造器)//1.获取Class类对象Class c1 = Dog.class;System.out.println(c1.getName());System.out.println(c1.getSimpleName());}//2.获取Constructor构造器对象@Testpublic void getConstructorInfo() throws Exception {Class c1 = Dog.class;Constructor[] cons = c1.getDeclaredConstructors();for(Constructor con : cons){System.out.println(con.getName() + "(" + con.getParameterCount() + ")");}Constructor con0 = c1.getDeclaredConstructor();System.out.println(con0.getName() + "(" + con0.getParameterCount() + ")");Constructor con1 = c1.getDeclaredConstructor(String.class, int.class);System.out.println(con1.getName() + "(" + con1.getParameterCount() + ")");con0.setAccessible(true); //暴力反射,强制访问Dog d1 = (Dog) con0.newInstance();System.out.println(d1);Dog d2 = (Dog) con0.newInstance("小白", 3);System.out.println(d2);}//3.获取Field成员变量对象@Testpublic void getFieldInfo() throws Exception {Class c1 = Dog.class;Field[] fields = c1.getDeclaredFields();for(Field field : fields){System.out.println(field.getName() + "(" + field.getType().getName() + ")");}Field field0 = c1.getDeclaredField("hobby");System.out.println(field0.getName() + "(" + field0.getType().getName() + ")");Dog d1 = new Dog("泰迪", 2);field0.setAccessible(true); //暴力反射field0.set(d1, "玩球");String hobby = (String) field0.get(d1);System.out.println(hobby);}//4.获取Method成员方法对象@Testpublic void getMethodInfo() throws Exception {Class c1 = Dog.class;Method[] methods = c1.getDeclaredMethods();for(Method method : methods){System.out.println(method.getName() + "(" + method.getParameterCount() + ")");}Method eat0 = c1.getDeclaredMethod("eat");System.out.println(eat0.getName() + "(" + eat0.getParameterCount() + ")");Method eat1 = c1.getDeclaredMethod("eat", String.class);System.out.println(eat1.getName() + "(" + eat1.getParameterCount() + ")");Dog d1 = new Dog("泰迪", 2);eat0.setAccessible(true); //暴力反射Object rs1 = eat0.invoke(d1); //d1.eat()System.out.println(rs1); //nullObject rs2 = eat1.invoke(d1,"牛肉");System.out.println(rs2); //cheers~}
}

Dog.java

package ReflectDemo;public class Dog {private String name;private int age;private String hobby;private void eat(){System.out.println("小狗吃饭");}public String eat(String food){System.out.println("小狗吃" + food);return "cheers~";}private Dog() {System.out.println("无参构造器执行");}private Dog(String name) {System.out.println("1号有参构造器执行");this.name = name;}public Dog(String name, int age) {System.out.println("2号有参构造器执行");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;}@Overridepublic String toString() {return "Dog{" +"name='" + name + '\'' +", age=" + age +", hobby='" + hobby + '\'' +'}';}
}

03 反射的作用

  • 可以得到一个类的成员变量、成员方法、构造器对象然后操作
  • 可以破坏封装性
  • 可以绕过泛型的约束
  • 可以设计Java高级框架
package ReflectDemo;import java.lang.reflect.Method;
import java.util.ArrayList;public class ReflectDemo3 {public static void main(String[] args) throws Exception{ArrayList<String> list = new ArrayList<>();list.add("赵敏");list.add("黄蓉");list.add("小龙女");list.add("王语嫣");//list.add(1988);//list.add(true);Class c1 = list.getClass();Method add = c1.getDeclaredMethod("add", Object.class);add.invoke(list, 9.9);add.invoke(list, true);System.out.println(list);}
}

在这里插入图片描述

04 案例:使用反射做一个简易版的框架

需求:对于任意一个对象,该框架都可以把对象的字段名和对应值保存到文件中去。

在这里插入图片描述

实现步骤:

① 定义一个方法,可以接收任意对象。

② 每收到一个对象后,使用反射获取该对象的Class对象,然后获取全部的成员变量。

③ 遍历成员变量,然后提取成员变量在该对象中的具体值。

④ 把成员变量名、和其值,写出到文件中去即可。

http://www.dtcms.com/a/394425.html

相关文章:

  • Linux 孤儿进程与进程的优先级和切换和调度
  • QML学习笔记(七)QML的基本数据类型
  • 基于51单片机电子钟闹钟12/24小时制LCD显示
  • 小程序开发全解析:从结构到API
  • 异步方法在C#中的使用
  • js时间戳转换日期格式 yyyy-mm-dd
  • 信号处理方法概述
  • 固定收益理论(五)债券投资归因模型
  • 【论文速递】2025年第18周(Apr-27-May-03)(Robotics/Embodied AI/LLM)
  • 3D视觉——求出目标物体在相机坐标系下的位姿信息
  • 固态和机械硬盘损坏后的不同
  • Linux 基础IO
  • pandawiki ai 无法生成摘要
  • m语言可视化log中的变量信息
  • MySQL:库操作和常用数据类型
  • uniapp实现view块级元素横竖屏切换
  • 【编号74】河北地理基础数据(道路、水系、四级行政边界、地级城市、DEM等)
  • Python: 将wxauto发布为接口,并部署为Windows服务
  • 2025年度SEO优化公司
  • 基于Markdown的静态网站生成器完全指南
  • hot100——第十一周
  • 嵌入式(2)——HAL_GetTick()
  • 《第18课——C语言结构体:从Java的“豪华别墅“到C的“集装箱宿舍“——内存对齐、位域抠门与指针破门的底层狂欢》
  • 旅游线路预约小程序怎么搭建?景区售票团购小程序怎么做?
  • Redis未来发展趋势:技术演进与生态展望
  • 怎么重新映射windows终端的按键的功能
  • 【秋招笔试】2025.09.20哔哩哔哩秋招笔试真题
  • string 容器
  • MySQL零基础学习Day1——安装与配置
  • mysql重启,服务器计划重启,如何优雅地停止MySQL?