java框架第二课(Reflection反射机制)

news2024/12/26 12:34:25

一.关于反射

(1)使用场景介绍

平常我们写代码时,都是已知类名,类的属性,构造方法,其他方法等信息,然后根据类名new对象,这个过程称为正向操作(例如:有一个管理员类,有账号和密码属性,还有一个set,get,eat方法,直接通过类名new对象,再通过对象名调用类的变量和方法。但在其他的一些场景如框架,servlet,xml文件中,可能并不知道该类有什么属性和方法等,可能只知道类的名字等,无法直接new对象为解决这个问题就引入了反射机制。

(1)如:servlet中的json格式转换将对象转为{属性名,值}的字符串

new ObjectMapper().writeValueAsString(result)    result就是传入的对象,json处理时并不知道这个传入的对象是什么,所以就要反过来根据对象名拿到该对象类的变量和属性,才能获得该对象的属性名和值。

(2) 如:在mybatis框架中要在mybatis的xml文件中配置类的名称从而找到类,将查询的结果自动通过类的名称映射到类的对象中,这就是使用了反射机制。

<insert id="insertAdminById" parameterType="Admin">
  insert into admin(account,password,gender) values (#{account},#{password},
 #{gender})
</insert>

(2)什么是java反射 

java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。

(3)在java中为什么要使用反射

就在上述场景中介绍一样,在java中平常不可避免的要用到反射,平常写业务代码(就是自己创建类new 对象,自己清楚类的属性和方法)用不到,但是一些其他场景不可避免地可能只知道类名,对象名等,要对该类(对象)的属性,方法操作就需要动态获取类(对象)的信息,使其只要知道任意类名或者对象名就能获得该类或者该对象的属性和方法并对其进行操作。

(4)反射机制图解

(5)java反射相关api

Java反射相关的类主要包括
Class 类型  :  可以动态将任意类转化为Class对象,然后根据Class对象获得类的对象)。
Constructor 构造方法 :可以通过该构造方法获得类的对象(前提获得Class对象)。
Method 方法 :  获得类的方法(前提获得Class对象)。
Field 属性:         获得类的属性(前提获得Class对象)。
除了Class外,其他类都位于java.lang.reflect包中
可见,反射API将类的类型、方法、属性都封装成了类,其中最重要的类是 Class,可以说,反射的使用都是从Class开始。

 以user(管理员类为例)

package com.ffyc.javareflection.model;

public class user {
    String account;
    String password;

    public user() {
        System.out.println("无参构造方法");
    }
     public void eat()
     {
         System.out.println("人吃饭");
     }
  public user(String account, String password) {
        System.out.println("有参构造方法");
        this.account = account;
        this.password = password;
    }

    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;
    }

    @Override
    public String toString() {
        return "user{" +
                "account='" + account + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

1.获得Class对象 

  已知类如何获得类中的属性和方法,通过CLass获得
        //方法一:已知类名获得Class对象
        Class aClass=Class.forName("com.ffyc.javareflection.model.user");
        System.out.println(aClass);
        //方法二:已知类获得Class对象
        Class bclass=user.class;
        System.out.println(bclass);
        //方法三:已知对象名获得Class对象
        user user=new user();
        Class cclass=user.getClass();
        System.out.println(cclass);

结果如图Class对象一样 

  获得类的对象有四种方法:
      1.new 对象
      2.对象序列化
      3.反射机制
      4.对象克隆

2.通过Class对象获得类的对象 

  //第一种:通过Class对象中的new获得类的对象
         Class aaclass=Class.forName("com.ffyc.javareflection.model.user");
           Object object=aaclass.newInstance();
        System.out.println(object);

3.通过构造方法获得类的对象


        //第二种:通过类中的构造方法来获得类的对象(公共的构造方法)
         //无参构造
        Constructor constructor=aaclass.getConstructor();
         Object object1= constructor.newInstance();
        System.out.println(object1);
         //有参构造
        Constructor constructor1=aaclass.getConstructor(String.class,String.class);
        Object object2=constructor1.newInstance("张三","111");
        System.out.println(object2);
        //获得所有公共的构造方法
        Constructor []constructors=aaclass.getConstructors();
        System.out.println(constructors.length);
         //获得任意的构造方法,包含私有的构造方法,一般不建议操作,因为打破了封装性
      Constructor [] constructor3=  aaclass.getDeclaredConstructors();
        System.out.println(constructor3.length);

4. 通过Method 方法获得类的方法(Method getMethod(String name, Class... parameterTypes) : 通过指定方法名,参数类型,返回一个Method实例)

Method 作用:

Method类将类中的方法进行封装,可以动态获得方法的信息,例如
getName:获得方法名字
getParameterTypes:获得方法参数类型
除了动态获得方法信息外,Method还能动态调用某一个对象的具体方法
invoke(Object obj, Object... args) :使用obj调用该方法,参数为args
        Class cclass=Class.forName("com.ffyc.javareflection.model.user");
         Object object=cclass.newInstance();
          Method method=cclass.getMethod("eat");
          String value= (String) method.invoke(object);
        System.out.println(value);

 

 5.Field 属性获得类的属性

Field类将类的属性进行封装,可以获得属性的基本信息、属性的值,也可以对属性进行赋值.
getName:返回属性的名字
set:设置属性值

 

 //通过私有属性get和set放法对类中私有属性进行赋值取值操作
        HashMap<String,String> hashMap=new HashMap<>();
        hashMap.put("account","admin");
        hashMap.put("password","111");

        Field [] fields=cclass.getDeclaredFields();//获得类中所有的成员变量包括私有的
        for (Field field:fields) {
            //根据属性名获得set放法名称
            String setmethod="set"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
            //通过class对象获得set方法对象
        Method method=  cclass.getMethod(setmethod,field.getType());
        //调用set方法
            method.invoke(object,hashMap.get(field.getName()));
        }
        System.out.println(object); //通过私有属性get和set放法对类中私有属性进行赋值取值操作
        HashMap<String,String> hashMap=new HashMap<>();
        hashMap.put("account","admin");
        hashMap.put("password","111");

        Field [] fields=cclass.getDeclaredFields();//获得类中所有的成员变量包括私有的
        for (Field field:fields) {
            //根据属性名获得set放法名称
            String setmethod="set"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
            //通过class对象获得set方法对象
        Method method=  cclass.getMethod(setmethod,field.getType());
        //调用set方法
            method.invoke(object,hashMap.get(field.getName()));
        }
        System.out.println(object);

二.反射的实例转json格式

package com.ffyc.javareflection.model;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Json {
    public static String json(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        String json="{";
        Class aclass=object.getClass();//先将传过来的对象转为class对象
        Field[] fields=aclass.getDeclaredFields();//然后获得该对象的所有属性
        for (Field field:fields) {
         String getfield="get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);//拿到get方法名
            //获得方法对象,getMethod(方法名,返回值类型)
             Method method= aclass.getMethod(getfield);
             //调用方法
            String value=(String)method.invoke(object);
            //把属性名和值拼接成键值
            json+=json+field.getName()+":"+value+",";
            json=json.substring(0,json.length()-1);//去掉多余逗号
            json+="}";
        }
        return json;
    }

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        car car = new car();
          car.setName("红旗");
          car.setColor("红色");

        user user = new user();
          user.setAccount("admin");
          user.setPassword("111");



        System.out.println(Json.json(car));
        System.out.println(Json.json(user));

    }
}

 

三.反射的好处和坏处 

  优点:
● 1. 增加程序的灵活性,可以在运行的过程中动态对类进行修改和操作
● 2. 提高代码的复用率,比如动态代理
● 3. 可以在运行时轻松获取任意一个类的方法、属性,并且还能通过反射进行动态调用

 缺点:

● 1. 反射会涉及到动态类型的解析,导致性能要比非反射调用更低
● 2. 使用反射技术通常要在一个没有安全限制的程序运行 .
● 3. 反射可以绕过一些限制访问的属性或者方法,可能会导致破坏代码本身的抽象 性

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2079870.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WEB渗透Win提权篇-BypassUAC

提权工具合集包&#xff08;免费分享&#xff09;&#xff1a; 夸克网盘分享 往期文章 WEB渗透Win提权篇-提权工具合集-CSDN博客 WEB渗透Win提权篇-RDP&Firewall-CSDN博客 WEB渗透Win提权篇-MSSQL-CSDN博客 WEB渗透Win提权篇-MYSQL-udf-CSDN博客 WEB渗透Win提权篇-Acc…

大模型基础环境部署之一:安装 Nvidia 的驱动(详细实操版)

一、系统准备前置条件 1、更新软件包列表 sudo apt-get update2、安装编译工具和依赖项 sudo apt-get install gcc sudo apt-get install make sudo apt-get install g注&#xff1a;如果在安装 g 时遇到错误消息&#xff1a;“***you do not appear to have libc header fi…

【C++ Primer Plus习题】6.2

问题: 解答: #include <iostream> #include <array> using namespace std;#define MAX 10int main() {array<float, MAX> arr;float sum0;float average0;int i 0;int count0;int bigger 0;for (i 0; i < MAX; i){cout << "请输入donation…

大数据技术之Flume 企业开发案例——聚合(7)

目录 聚合 1&#xff09;案例需求&#xff1a; 2&#xff09;需求分析 3&#xff09;实现步骤&#xff1a; 准备工作 创建 flume1-logger-flume.conf 创建 flume2-netcat-flume.conf 创建 flume3-flume-logger.conf 执行配置文件 聚合 1&#xff09;案例需求&#x…

华为eNSP:路由器子接口配置

一、拓扑图 二、 路由器配置 [R1]int g0/0/0.1#进入子接口 [R1-GigabitEthernet0/0/0.1]ip add 192.168.1.254 24#配置子接口地址 [R1-GigabitEthernet0/0/0.1]dot1q termination vid 10#标记终止的vid编号 [R1-GigabitEthernet0/0/0.1]arp broadcast enable #开启子接口的arp…

Keilv5 逻辑分析仪的使用

声明&#xff1a;基于视频【事件驱动型编程和 QP/C 框架】所做的笔记 Keilv5逻辑分析仪是Keil MDK集成开发环境&#xff08;IDE&#xff09;中的一个工具&#xff0c;用于帮助开发人员进行嵌入式系统的调试和分析。 它的作用主要有&#xff1a; 监测信号&#xff1a;Keilv5逻…

DBSCAN算法详解

1. 算法原理 DBSCAN&#xff08;Density-Based Spatial Clustering of Applications with Noise&#xff09;是一种基于密度的聚类算法&#xff0c;主要用于发现数据中的任意形状的簇&#xff0c;并能够有效地识别噪声点。它的基本思想是通过密度来定义簇&#xff0c;即在数据…

Python -- GUI图形界面编程—GUI编程实例 博主也在持续学习中[ 持续更新中!!! 欢迎白嫖 ]

本文继上篇文章http://t.csdnimg.cn/mJlmW继续介绍GUI的图形界面编程&#xff08;相关视频是哔站上的应该搜这个题目就能找到&#xff09;&#xff0c;文章还是很基础的&#xff0c;目前博主处于有一点基础的状态。 文章的主要介绍了依旧非常重要的结构tinkter库、常见的三种布…

Patch-Package:一款灵活的开源依赖修复工具

一、背景 在现代软件开发中&#xff0c;开发者通常依赖大量的开源库来加快开发进程。然而&#xff0c;随着时间的推移&#xff0c;可能会遇到一些问题&#xff1a; 开源包的缺陷&#xff1a;开源库可能存在 Bug 或者与项目不兼容的问题。开发者可以自己修复这些问题&#xff0…

QML控件: 动画输入框 LineEdit PySide6

1. 前言 本代码为扫地僧-smile原创, 废话不多说, 直接看效果图由于录制的这个GIF图掉帧严重, 实际动画效果非常细腻 2.看代码 控件模块代码如下 SmileLineEdit.qml import QtQuick import QtQuick.Controls/* __author__: 扫地僧-smile */Rectangle {// 属性property int …

这些年使用Delphi的成果

成果1&#xff1a; 收到了一件文化衫 成果2&#xff1a;被评为亚洲专家&#xff0c;收到了一套Delphi7 光碟找不到了。

Arista与英伟达IB网络竞争格局分析

悄然崛起的英伟达新对手 英伟达都有哪些对手&#xff1f; 当然首选AMD和英特尔。AMD具备AI加速卡业务&#xff0c;融合CPU和GPU设计能力&#xff1b;英特尔作为x86架构的开创者&#xff0c;如今也涉足AI加速卡领域。它们的产品在参数上与英伟达对标&#xff0c;同时在定位和售…

江西生物科技职业学院春雨宣讲团丨弘扬西柏坡精神,共绘时代新篇章

今年五月&#xff0c;江西生物科技职业学院春雨宣讲团获批共青团中央2024年全国大学生西柏坡精神志愿宣讲团之一。 秉承传承红色文化、弘扬西柏坡精神的崇高使命&#xff0c;该宣讲团成员自7月3日起至8月20日&#xff0c;踏上了深入江西省南昌市、九江市、景德镇市、吉安市等地…

走线特征阻抗

ns/ft中ft代表英尺 :1ft0.3048m30.48cm 对于FR-4板&#xff0c;1.017*根号&#xff08;4.5&#xff09;2.121ns/ft 也即每英寸的传输时间为2.121ns&#xff0c;30.48/2.12114.6cm/ns&#xff1b; 当差分线中以相同的驱动电压驱动时&#xff0c;我们称之为偶模&#xff0c;当以…

Eclipse 自定义字体大小

常用编程软件自定义字体大全首页 文章目录 前言具体操作1. 打开设置对话框2. 打开字体设置页面3. 找到Text Font&#xff0c;点击修改4. 修改字体 前言 Eclipse 自定义字体大小&#xff0c;统一设置为 Courier New &#xff0c;大小为 三号 具体操作 【Windows】>【Perfer…

IROS 2024不容错过的4大理由

01 IROS是国际机器人顶会 关于机器人学术顶会&#xff0c;听IROS 2025大会主席、上海交通大学王贺升教授怎么说。 ICRA 2024专辑&#xff1a;上交王贺升教授聊机器人学术顶会【度量访问】 02 未来一年难得的国际交流机会 ICRA 2025 将在美国亚特兰大举办&#xff1b; RSS 20…

zookeeper命令 及 ACL控制

1命令 登录 zkCli.sh -server 192.168.58.81:2128 登录ip zkCli.sh 登录本机 关闭会话 close 帮助文档 help 让zk数据发生变化都是一次事务 create创建 create /aaa 创建持久节点 create -e /aaa/bbb 创建临时节点 create /aaa/bbb/ccc 不能创建成功 …

docker 拉取镜像超时

docker 拉取镜像超时报错如下&#xff1a; error pulling image configuration: Get xxx:443: i/o timeout [rootlocalhost docker]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx e4fff0779e6d: Pulling fs layer 2a0cb278fd9f: Pulli…

GB28181 SDP协议学习笔记

GB28181 SDP协议学习笔记 (GB/T28181-2016 附录F 100页) 定义 示例 v0 o34000000002000000001 0 0 IN IP4 192.168.100.100 sDownload u34020000001310000001:3 cIN IP4 192.168.100.100 t1498173736 1498174066 mvideo 10122 TCP/RTP/AVP 96 98 97 arecvonly artpmap:96 P…

MySQL索引详解:原理、数据结构与分析和优化

在数据库管理系统中&#xff0c;索引是提高查询性能、优化数据存储结构的重要工具。MySQL作为广泛使用的开源关系型数据库管理系统&#xff0c;其索引机制对于提升数据库操作效率具有至关重要的作用。本文将围绕“MySQL索引详解&#xff1a;原理、数据结构与分析和优化”这一主…