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

第十天:Java反射

反射

反射就是:加载类,并编写代码获取类中的成员变量,方法,构造器等。

注意:反射,注解,动态代理就是用来学习框架做框架的,在平时业务开发需求上很少用到。

1 反射学什么?

2 获取Class对象的三种方式

2.1 通过类名.class获取

Class c1=类名.class

Class c1=Student.class;
System.out.println(c1.getName());//全类名=包名+类名
System.out.println(c1.getSimpleName());//简名

2.2 通过Class提供的方法forName()

Class.forName(“填自己想获得的类的全类名”)

Class c2=Class.forName("com.xie.Student");

2.3 通过对象提供的方法

Class c3=对象.getClass()

Student student=new Student();
Class c3=student.getClass();

3 获取类的构造器

3.1 getConstructors()

获取所有公共构造函数(在开发中一般不会用这个)

Class c1=Cat.class;
Constructor[] cons=c1.getConstructors();

3.2 getDeclaredConstructors()

获取所有构造函数,可以是公共、私有或受保护的构造函数。(开发中推荐使用)

Class c2=Cat.class;
Constructor[] cons=c2.getDeclaredConstructors();

3.3 getConstructor(Class<?>… parameterTypes)

获取指定参数类型的公共构造函数

Class c1=Cat.class;
Constructor constructor=c1.getConstructor();

3.4 getDeclaredConstructor(Class<?>… parameterTypes)

获取指定参数类型的构造函数,可以是公共、私有或受保护的构造函数(推荐)

Class c2=Cat.class;
Constructor constructor=c2.getDeclaredConstructor(String.class,int.class);

4 获取类的构造器的作用

作用:初始化对象并返回

4.1 初始化对象newInstance(参数)

调用此构造器对象表示的构造器,并传入参数,完成对象初始化,并返回。(不能调用私有的构造器)

Class c1=Cat.class;
Constructor constructor=c1.getDeclaredConstructor(String.class,int.class) ;
Cat cat=(Cat)constructor.newInstance("小橘猫",2);

4.2 setAccessible(true)

绕过私有成员的访问限制,访问/修改私有字段、方法或构造方法。

Class c1=Cat.class;
Constructor constructor=c1.getDeclaredConstructor();
constructor.setAccessible(true);
//表示禁止检查访问控制,因为Cat的无参构造方法是私有的,newInstance()
//无法访问,因此使用setAccessible(true),后续newInstance()
//才可以调用
Cat cat=(Cat)constructor.newInstance();
System.out.println(cat);

5 获取类的成员变量

5.1 getFields()

获取所有 public 字段(包括继承的)

Class c1=Cat.class;
Field[] fields=c1.getFields();
for(Field f:fields){System.out.println(f.getName()+"-->"+f.getType());
}

5.2 getDeclaredFields()

获取所有字段(包括 private,但不包括继承的)

推荐用这个

Class c1=Cat.class;
Field[] fields=c1.getDeclaredFields();
for(Field f:fields){System.out.println(f.getName()+"-->"+f.getType());
}

5. 3 getField(“参数”)

获取指定名称的 public 字段(包括继承的)

Class c1=Student .class;
Field f1=c1.getDeclaredField("name");

5.4 getDeclaredField(“参数”)

获取指定名称的字段(包括 private,但不包括继承的)

推荐用这个

Class c1=Cat.class;
Field f=c1.getDeclaredField("age");
System.out.println(f.getType());

6 使用成员变量

6.1 void set(Object obj, Object value)

修改指定对象的字段值。

Class c=Cat.class;
Field cName=c.getDeclaredField("name");
Field cAge=c.getDeclaredField("age");
Constructor constructor =c.getDeclaredConstructor();
//newInstance()无法调用私有构造器
Cat cat = (Cat) constructor.newInstance();
cName.setAccessible(true);
cName.set(cat, "加菲猫") ;
cAge.setAccessible(true) ;
cAge.set(cat, 18);

6.2 Object get(Object obj)

取变量的值

int age=(int) cAge.get(cat);

6.3 setAccessible(true)

设置为true ,表示禁止检查访问控制(暴力反射)

cAge.setAccessible(true) ;

7 获取类的成员方法

7.1 getMethods()

获得该类所有方法(只获取带有public修饰的方法)

Class dog=Dog.class;
//获取类的全部成员方法
Method[] methods=dog.getMethods();

7.2 getDeclaredMethods()

获得该类所有方法

Class dog=Dog.class;
//获取类的全部成员方法
Method[] methods=dog.getDeclaredMethods();

7.3 getDeclaredMethod(String name, Class…<?> parameterTypes)

获得该类某个方法

7.3.1 无参的
Class taidi=Dog.class;
Method eat=taidi.getDeclaredMethod("eat");//拿无参的eat方法
7.3.2 有参的
Class jing=Dog.class;
Method eat1=jing.getDeclaredMethod("eat", String.class);//拿有参的eat方法

8 执行方法

8.1 public Object invoke(Object obj, Object… args)

触发某个对象的该方法执行

8.1.1无参方法
Class taidi=Dog.class;
Method eat=taidi.getDeclaredMethod("eat");//拿无参的eat方法
System.out.println(eat.getName()+"-->"+eat.getParameterCount()+"-->"+eat.getReturnType());
//触发该无参方法
Dog dog1=new Dog();
eat.setAccessible(true);//因为无参的eat方法是private的因此设置暴力发射
Object rs=eat.invoke(dog1);//调用无参的eat方法,用dog1对象触发调用
System.out.println(rs);//返回null,因为eat无参方法的返回类型是void的
8.1.2 有参方法
//获取某个方法(有参的)
Class jing=Dog.class;
Method eat1=jing.getDeclaredMethod("eat", String.class);
System.out.println(eat1.getName()+"-->"+eat1.getParameterCount()+"-->"+eat1.getReturnType());
//调用有参的eat方法
Dog dog2=new Dog();
eat1.setAccessible(true);
String rs1=(String) eat1.invoke(dog1,"狗粮");//调用有参的eat方法,用dog2对象触发调用
System.out.println(rs1);
System.out.println("===========");

9 反射的作用,应用场景

基本作用:

  • 得到一个类的全部成分然后进行操作
  • 破坏封装性
  • 最重要的用途:适合做java框架,基本上,主流的框架都会基于反射设计出一些通用的功能

9.1 使用反射做一个简易框架

public class ObjectFrame {//目标:保存任意对象的字段和其数据到文件中去public static void saveObject(Object object) throws IllegalAccessException, FileNotFoundException {PrintStream ps = new PrintStream(new FileOutputStream("src\\data.txt", true));//obj是任意对象,到底有多少个字段可以保存Class c=object.getClass();String className=c.getSimpleName();ps.println("-----"+className+"-----");//从这个类中提取他的全部成员变量Field[] fields=c.getDeclaredFields();//遍历每个成员变量for(Field f:fields){//拿到成员变量的名字String name = f.getName();//拿到成员变量在对象中的数据f.setAccessible(true);String value= f.get(object) +"" ;ps.println(name+"="+value);}ps.close();}
}
public class TestFrame {public static void save() throws FileNotFoundException, IllegalAccessException {Student s1=new Student("张三",18,'男',178.9,"打篮球");Teacher t1=new Teacher("黎明",8000.1);ObjectFrame.saveObject(s1);ObjectFrame.saveObject(t1);}public static void main(String[] args) throws FileNotFoundException, IllegalAccessException {save();}
}
xception {Student s1=new Student("张三",18,'男',178.9,"打篮球");Teacher t1=new Teacher("黎明",8000.1);ObjectFrame.saveObject(s1);ObjectFrame.saveObject(t1);}public static void main(String[] args) throws FileNotFoundException, IllegalAccessException {save();}
}
http://www.xdnf.cn/news/771553.html

相关文章:

  • 灵动相册,助力教学:在线教学场景的图片管理利器——仙盟引渡仙君-智能编程——仙盟创梦IDE
  • 通俗理解“高内聚,低耦合”
  • react 生命周期
  • “等待-通知”机制优化(一次性申请)循环等待
  • 电子电路:4017计数器工作原理解析
  • 【Java EE初阶】计算机是如何⼯作的
  • “application/json“,“text/plain“ 分别表示什么
  • 【C#朗读文本DLL动态按钮控件组及按钮事件文本框拖放数据】2022-1-21
  • 【Go-补充】ioReader + ioWriter + bufio
  • Charles青花瓷抓取外网数据包
  • 【笔记】Windows 部署 Suna 开源项目完整流程记录
  • 格密码-LWE问题
  • Python基础:人生重开模拟器(小游戏)
  • 编译原理实验 之 TINY 之 语义分析(第二次作业)
  • PHP舆情监控分析系统(9个平台)
  • 机器学习:支持向量机(SVM)原理解析及垃圾邮件过滤实战
  • Qt信号与槽机制深度解析
  • 【Godot】如何导出 Release 版本的安卓项目
  • 【笔记】Windows 下载并安装 ChromeDriver
  • IO模型IO模型
  • ISO18436-2 CATII级振动分析师能力矩阵
  • 振动分析师(ISO18436-2)四级能力矩阵 - 简介
  • ROS机器人和NPU的往事和新知-250602
  • python打卡训练营打卡记录day43
  • 阿里云服务器-解决宝塔登录不成功
  • DAY 41 简单CNN
  • 审计 - 风险应对 - 控制测试
  • springboot04
  • 2025年十大AI幻灯片工具深度评测与推荐
  • C++.cstring string