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

[ Java 反射机制 ]

目录

一. 概述 

1. 前提

2.定义:

3.作用:

4.如何获取类信息:

5. Class类

1.  获得任意类的class对象

2. Java中创建对象的方式

3.通过Class类获得类中属性

4. 通过Class类对象 获得类中的方法

5.举例

6. 反射的优缺点

(1)优点:

(2)缺点:


一. 概述 

1. 前提

已知一个类,通过new创建这个类的对象, 使用对象去调用属性和方法. 用哪个对象,就在代码中new

在业务代码中这样写没有问题,而对于框架来说,这样写就不行了.

由于框架要处理项目中任意的类,为任意类创建出一个实例(对象)

所以框架需要满足一套机制,即只需要写一套代码,就可以创建任意类对象

    在接触框架之后, 用法就发生了一些变化:

2.定义:

       程序在运行时只需要知道字符串类地址,就可以创建该类的对象,能够动态获取类信息,动态创建对象,并且能够调用任意对象的方法或操作其属性的机制称为Java的反射机制

3.作用:

       根据类的地址(字符串类地址"com.ffyc.news.model.Admin"),动态获得类信息,动态创建对象,调用对象的属性和方法

4.如何获取类信息:

java.long.Class  类

在方法区中(存储类信息) ,  为每一个类创建一个class类的对象,可以通过class类的对象获取他所表示的类中的任何信息

一个Class类对象表示一个运行时的Java类信息,我们可以通过class类提供的方法,获取类中的信息,并创建类的对象,所有Class类是Java反射机制的根基

Class-----类型    Method------方法    Filed------属性

5. Class类

1.  获得任意类的class对象

(1).已知类的字符串地址  Class.forName();

(2).类名.class

(3).对象名.getClass()

package com.ffyc.javareflect;public class User {private String account;private  String password;public String phone;public String address;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public User(){System.out.println("user无参构造方法");}public User(String account, String password, String phone) {this.account = account;this.password = password;this.phone = phone;}public void eat(){System.out.println("无参eat");}public void eat(String foodName){System.out.println("有参的eat");}public String getAccount() {return account;}public void setAccount(String account) {this.account = account;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}
}
package com.ffyc.javareflect;public class Test1 {public static void main(String[] args) throws ClassNotFoundException {/*传统的类使用:User user = new User();//已知有一个user类,我们创建该类的对象对于框架来说,面对当得可能是未知的*//*获得任意类的class对象*///方式一:已知类的字符串地址String className ="com.ffyc.javareflect.User";//框架常用Class a= Class.forName(className);System.out.println(a);//方式二:类名.classClass b= User.class;//mybatis 中使用 接口.方法System.out.println(b);//方式三: 对象名.getClass()User user = new User();Class c = user.getClass();//把当前类型转为Class类型System.out.println(b==a);//true 地址相同System.out.println(c==a);//true 地址相同System.out.println(b==c);//true 地址相同}
}

2. Java中创建对象的方式

        1.new对象
        2.io中 对象输出流(反序列化)
        3.反射机制 通过Class类对象中的newInstance();
        4.对象克隆

3.通过Class类获得类中属性

        getField("Phone")     获取类中指定的公共属性
        getFields()                获得类中所有的公共属性
        getDeclaredFields()  获得类中所有的属性

package com.ffyc.javareflect;import java.lang.reflect.Field;public class Test2 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {String className ="com.ffyc.javareflect.User";//获得类的class对象Class cl =Class.forName(className);//调用 Class类中的newInstance() 还会调用类中无参的构造方法,创建出一个对象Object obj = cl.newInstance();System.out.println(obj);//输出对象/*通过Class类获得类中属性getField("Phone") 获取类中指定的公共属性getFields()       获得类中所有的公共属性getDeclaredFields() 获得类中所有的属性*/Field accField = cl.getField("account");System.out.println(accField);//拿不到,因为account是私有的,只能拿公共的Field[] pubfields = cl.getFields();System.out.println(pubfields.length);for(Field field:pubfields){field.set(obj,"aaa");System.out.println(field);}Field[] fields = cl.getDeclaredFields();for(Field field:fields){System.out.println(field);//输出所有属性field.setAccessible(true);//设置对私有属性是否可以操作的开关,默认关闭field.set(obj,"aaaa");//给属性赋值System.out.println(field.get(obj));//拿到属性的值}}
}

4. 通过Class类对象 获得类中的方法

getMethods() 获得类中所有的公共方法 

package com.ffyc.javareflect;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class Test3 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {/*Java中创建对象的方式1.new对象2.io中 对象输出流(反序列化)3.反射机制 Class类中的newInstance();4.对象克隆*/String className ="com.ffyc.javareflect.User";//获得类的class对象Class cl =Class.forName(className);//调用 Class类中的newInstance() 还会调用类中无参的构造方法,创建出一个对象Object obj = cl.newInstance();/*通过Class类对象 获得类中的方法getMethods() 获得类中所有的公共方法*/Method method = cl.getMethod("eat");System.out.println(method);//拿到无参的eat方法method.invoke(obj);//调用获得的方法//getMethod("方法名",参数类型) 获得指定方法名 指定类型的公共成员方法Method method1= cl.getMethod("eat",String.class);System.out.println(method1);method1.invoke(obj,"凉皮");//给所调用的有参的方法传参}
}

 5.举例

forName()

newInstance()

getField("phone"); 获得类中指定名称的公共属性

getFields(); 获得类中所有的公共属性

getDeclaredFields(); 获得类中所有属性

getDeclaredFields("phone")

getDeclaredMethods() 获得类中所有的成员方法

getMethods() 获得类中所有公共的成员方法

getMethod("eat");

getDeclaredMethod("eat");

package com.ffyc.javareflect;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;public class Demo1 {/*模拟mybatis  自动数据封装*/public static void putData(String classname, Map<String, Object> map) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {//获得传入的类地址的class对象Class cl = Class.forName(classname);//创建一个传入类的对象Object obj = cl.newInstance();//动态获得类中的属性Field[] fields =cl.getDeclaredFields();for(Field field: fields){//首先获得属性名称(account password color....)String name = field.getName();System.out.println(name);//通过属性的名字找到属性的set方法名String methodName ="set"+(char)(name.charAt(0)-32)+(name.substring(1));System.out.println(methodName);//通过set方法名字获得对应的set方法Method setmethod = cl.getMethod(methodName,field.getType());setmethod.invoke(obj,map.get(name));//调用方法 赋值}System.out.println(obj);}public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {//map模拟数据库中查询到到的数据Map<String,Object> map = new HashMap<>();map.put("account","admin");map.put("password","111");map.put("phone","17511111111");//classname 模拟resultTypeString classname = "com.ffyc.javareflect.User";Demo1.putData(classname,map);Map<String,Object> map1 = new HashMap<>();map.put("name","宝马");map.put("color","红色");//classname 模拟resultTypeString classname1 = "com.ffyc.javareflect.Car";Demo1.putData(classname1,map1);}}

6. 反射的优缺点

(1)优点:

       通过反射机制,可以动态获得任意类中的信息,调用任意对象中的方法,增加程序编写的灵活性和代码的复用性 例如框架 -----写一套代码就可以处理任意类 ; 公共组件...

(2)缺点:

       反射机制使用效率低,可以对私有成员进行操作,打破封装性,使用反射机制时,应该尽量避对私有成员进行操作

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

相关文章:

  • 元宇宙与医疗健康的深度融合:重构诊疗、培训与健康管理新生态
  • 《算法闯关指南:优选算法--二分查找》--21.山峰数组的的峰顶索引,22.寻找峰值
  • h5游戏免费下载:弗莱迪的物理实验
  • C++ 学习 —— 03 - 类
  • 元宇宙与金融的深度融合:重构服务生态与价值边界
  • 用js做的网站页面设计理念万能模板
  • 做音乐网站的目的在线画画网站
  • 【C语言】两个字符串的相似度检查
  • 从零搭建 RAG 智能问答系统 4:从多模态架构到 Milvus 向量存储实践
  • WVP国标级联(GB/T 28181)完整搭建指南:环境准备与实战配置
  • Topaz Video AI for Mac AI视频无损放大 视频画质增强
  • 什么是组网架构
  • 讲一下elastic search 的分词原理
  • 玩转 Go 表达式引擎:expr 实战指南
  • 【IO多路转接】高并发服务器实战:Reactor 框架与 Epoll 机制的封装与设计逻辑
  • 企业网站建设毕业设计论文龙岗网站建设开发设计公司
  • 力扣热题100道之238除自身以外数组的乘积
  • 把AI装进OS、批量落地智慧服务,智能手机革命2.0来了
  • 防爆手机可以通过普通智能手机改装吗?
  • 宇树H2仿生机器人登场
  • 语音识别技术之FireRedASR
  • 有什么指标可以判断手机是否降频
  • 禾赛科技与广和通战略合作,联合推出机器人解决方案加速具身智能商业化落地
  • 石家庄网站开发哪家好企业网站建设网站模板
  • Z3 Technology-适用于无人机和机器人的 4K 高清摄像机和视频编码器
  • 济南天桥区做网站的怎样做app推广
  • 建设河南网站外贸网站建设盲区
  • 运维逆袭志·第4期 | 安全风暴的绝地反击 :从告警地狱到智能防护
  • Java-集合求差集,如果B集合中的id在A集合中存在就移除,如果不在就返回A集合
  • 微服务即时通讯系统——整体架构和组件(1)