当前位置: 首页 > 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.dtcms.com/a/226997.html

相关文章:

  • vscode 插件 eslint, 检查 js 语法
  • 导入典籍数据
  • Kotlin 中 companion object 扩展函数和普通函数区别
  • 【Delphi】实现在多显示器时指定程序运行在某个显示器上
  • 使用 OpenCV (C/C++) 通过二值化增强车牌识别
  • 如何选择合适的哈希算法以确保数据安全?
  • AJAX对于XML和JSON的处理
  • 腾讯云 Python3.12.8 通过yum安装 并设置为默认版本
  • dify应用探索
  • 基于ubuntu和树莓派环境对游戏进行移植
  • imx6ull(0):烧录、启动
  • JavaSE:面向对象进阶之内部类(Inner Class)
  • Uiverse.io:免费UI组件库
  • 通信革新与网络安全探索与创新:开启未来之门
  • MySQL-多表关系、多表查询
  • 绿盟 IPS 设备分析操作手册
  • 详细解析2MHz和3MHz压电陶瓷片的区别
  • TomSolver 库 | config详解及其测试
  • 嵌入式Linux 期末复习指南(下)
  • Java如何读取CSV文件并将数据放入对象中详解
  • GMDCMonitor企业版功能分享0602
  • Python列表、字典、元组、集合
  • 系统级 EOS 测试方法 - System Level EOS Testing Method
  • 【设计模式-3.5】结构型——装饰器模式
  • window ollama部署模型
  • Node.js 中使用 Express 框架系统详细讲解
  • 有公网ip但外网访问不到怎么办?内网IP端口映射公网连接常见问题和原因
  • 制作个人Github学术主页
  • Redis持久化机制详解:RDB与AOF的深度剖析
  • 超声波测距三大算法实测对比