我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何理解Java反射技术

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何理解Java反射技术

本篇内容介绍了“如何理解Java反射技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一、前期概要

1、 什么是反射

Java 反射机制在程序运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种 动态的获取信息 以及 动态调用对象的方法 的功能称为 java 的反射机制。反射中的反的理解:在使用的之前,提前不知道需要使用什么类型的对象。只是在调用的时候,才知道要调用的对象类型。这种反其道而行的就是反射中反的理解。程序执行分为编译器和运行期,编译时刻加载一个类就称为静态加载类,运行时刻加载类称为动态加载类,核心思想 让你在写代码的时候可以更加灵活,降低耦合,提高代码的自适应能力。反射框架提供如下常用的核心功能:1.在运行时判断任意对象所属的类;2.在运行时构造任意一个类的对象;3.在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法);4.在运行时调用任意一个对象的方法;

2、反射的主要用途

通用框架,很多框架都是配置化的(比如Spring通过xml配置Bean), 为了保证框架的通用性,可能需要根据不同的配置文件加载不同的对象或者类,调用不同的方法,这个时候就需要反射,运行时动态加载需要加载的对象。

3、缺点

· 性能不佳 - 由于java反射动态解析类型,因此涉及扫描类路径以查找要加载的类的处理,从而导致性能降低。

· 安全限制 - Reflection需要运行时权限,这些权限可能不适用于在安全管理器下运行的系统。由于安全管理器,这可能导致应用程序在运行时失败。

· 安全问题 - 使用反射,我们可以访问我们不应该访问的部分代码,例如,我们可以访问类的私有字段并更改它的值。这可能是严重的安全威胁,并导致您的应用程序出现异常行为。

· 高维护 - 反射代码很难理解和调试,在编译时也无法找到代码的任何问题,因为这些类可能不可用,使其不太灵活且难以维护。

00001. Class 对象

00002. 类名

00003. 修饰符

00004. 包信息

00005. 父类

00006. 实现的接口

00007. 构造器

00008. 方法

00009. 变量

00010. 注解

二、获得 Class 对象

在运行期间,一个类,只有一个Class对象产生

1、类的静态方法(常用) :

00001. 说明获取指定的类完整的路径相关联接口的Class对象。

00002. 方法// 掌握public static Class<?> forName(String className)// 了解public static Class<?> forName(String className, boolean initialize,ClassLoader loader)

00003. 举个栗子Class clazz = Class.forName("http://com.wener.reflect.Xxx")// 或者 Class clazz = Class.forName("http://com.wener.reflect.Xxx",initialize,this.getClass().getClassLoader)

 说明任何数据类型(包括基本数据类型)都有一个“静态”的class属性

 方法Class<?> cls = 类型.class;

 举个栗子Class<String> cls = String.class;System.out.println(cls.toString());

 说明通过对象的实例来返回Class对象

 方法Class<?> cls = instance.getClass()

 举个栗子public class User {}User user = new User();Class<? extends User> clz = user.getClass();

 方法// 通过字段名,返回一个具体的具有public属性的成员变量(包括父类的)Field getField(String name) // 通过字段名所有已声明的所有成员变量(私有的 默认的 共有的),但不能得到其父类的成员变量Field getDeclaredField(String name)

 举个栗子public class User {private String name;public String detail;}public static void main(String[] args) {try {Class<?> cls = Class.forName("com.wener.reflect.demo1.User");Field detail = cls.getField("detail");System.out.println(detail);Field name = cls.getDeclaredField("name");System.out.println(name);} catch (ClassNotFoundException | NoSuchFieldException e) {e.printStackTrace();}}

 说明反射非常强大,但是学习了之后,会不知道该如何使用,反而觉得还不如直接调用方法来的直接和方便。但等我们后面接触到一些框架之后才会有一些感触

 测试类package com.wener.reflect.demo2; public class ReflectDemo1 { public void say() { System.out.println("ReflectDemo1"); } } public class ReflectDemo2 { public void say() { System.out.println("ReflectDemo2"); } }

 配置文件reflect.propertiesclass=ReflectDemo2. method=say

 测试代码public static void main(String[] args) { //从spring.txt中获取类名称和方法名称 File springConfigFile = new File("/Users/zhangwei/work/IdeaProjects/JavaExample/ReflectExample/class="lazy" data-src/reflect.properties"); Properties properties = new Properties(); try { properties.load(new FileInputStream(springConfigFile)); String className = (String) properties.get("class"); String methodName = (String) properties.get("method"); //根据类名称获取类对象 Class cls = Class.forName(className); //根据方法名称,获取方法对象 Method m = cls.getMethod(methodName); //根据构造器,实例化出对象 Object service = cls.newInstance(); //调用对象的指定方法 m.invoke(service); } catch (IOException | InvocationTargetException | NoSuchMethodException | IllegalAccessException | ClassNotFoundException | InstantiationException e) { e.printStackTrace(); } }

 优点当需要从调用第一个类的方法,切换到调用第二类的方法的时候,不需要修改一行代码

1、通过配置文件动态切换六、综合案例返回值 方法说明String getName()获取方法的名称int getModifiers()获取方法的修饰符Class<?> getReturnType() Type getGenericReturnType返回方法的返回值类型Class<?>[] getParameterTypes() Type[] getGenericParameterTypes()返回方法的参数(列表)Class<?>[] getExceptionTypes() Type[] getGenericExceptionTypes()返回方法的异常信息4、其它API

 举个栗子public class User { private String name = "木木"; public String detail = "hello"; private int age; private BigDecimal balance; public void increment() { this.age++; System.out.println(age); } public BigDecimal getBalance() { return balance; } public void setBalance(BigDecimal balance) { this.balance = balance; } private void say(int num) { System.out.println(num + "号技师"); } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", detail='" + detail + '\'' + '}'; } } public class TestReflectUser { public static void main(String[] args) { reflectMethod(); } public static void reflectMethod() { try { // 1.实例化class对象 Class<?> cls = Class.forName("com.wener.reflect.demo1.User"); // 2.实例化User对象 Object o = cls.newInstance(); // 3.获取set方法 Method method = cls.getMethod("increment"); // 4 执行方法 method.invoke(o); // 有参数无返回值 Method setBalance = cls.getMethod("setBalance", BigDecimal.class); Object methodSet = setBalance.invoke(o, new BigDecimal(100.00)); System.out.println(methodSet); // 有返回值值无参数 Method methodGet = cls.getMethod("getBalance"); Object invoke = methodGet.invoke(o); System.out.println(invoke); // 获取私有的方法 Method say = cls.getDeclaredMethod("say", int.class); // 运行时取消访问权限检测机制 say.setAccessible(true); // 执行方法 say.invoke(o, 1); } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } }

使用参数 args 在 obj 上指派该对象所表示方法的结果 

 方法Object invoke(Object obj, Object... args)

 参数说明

· obj - 从中调用底层方法的对象,必须是实例化的对象

· args - 用于方法调用的参数,是个Object数组,因为参数有可能有多个

 返回值

3、调用方法

 方法// 返回类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 public Method[] getDeclaredMethods() throws SecurityException// 返回某个类的所有公用(public)方法,包括其继承类的公用方法。 public Method[] getMethods() throws SecurityException

 举个栗子public class TestReflectUser { public static void main(String[] args) { reflectMethod(); } public static void reflectMethod() { try { // 1.实例化class对象 Class<?> cls = Class.forName("com.wener.reflect.demo1.User"); // 2.实例化User对象 Object o = cls.newInstance(); // 获取所有的共有的方法(包括父类的方法) Method[] methods = cls.getMethods(); for (Method method1 : methods) { System.out.println(method1.getName()); } // 获取所有的方法(包括私有的,共有的,默认的) Method[] declaredMethods = cls.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod.getName()); } } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } }

2、获取所有的方法

 方法// 方法返回一个特定的方法,其中第一个参数为方法名称,后面的参数为方法的参数对应Class的对象 public Method getMethod(String name, Class<?>... parameterTypes)

 举个栗子public class User { private String name = "木木"; public String detail = "hello"; private int age; private BigDecimal balance; public void increment() { this.age++; System.out.println(age); } public BigDecimal getBalance() { return balance; } public void setBalance(BigDecimal balance) { this.balance = balance; } private void say(int num) { System.out.println(num + "号技师"); } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", detail='" + detail + '\'' + '}'; } } public class TestReflectUser { public static void main(String[] args) { reflectMethod(); } public static void reflectMethod() { try { // 1.实例化class对象 Class<?> cls = Class.forName("com.wener.reflect.demo1.User"); // 2.实例化User对象 Object o = cls.newInstance(); // 3.获取increment方法 Method method = cls.getMethod("increment"); // 有参数无返回值 Method setBalance = cls.getMethod("setBalance", BigDecimal.class); // 有返回值值无参数 Method methodGet = cls.getMethod("getBalance"); // 获取私有的方法 Method say = cls.getDeclaredMethod("say", int.class); } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } }

1、获取单个方法五、方法操作

 方法// 将指定对象参数上的此Field对象表示的字段设置为指定的新值 field.set(Object obj,Object value)

 参数说明

· Object obj: 字段所在的类的实例对象

· Object value : 新值

 注意// 如果要给私有变量赋值必须取消权限的访问控制 field.setAccessible(true);

 举个栗子public static void main(String[] args) { try { // 1 实例化Class对象 Class<?> cls = Class.forName("com.wener.reflect.demo1.User"); Field detail = cls.getField("detail"); System.out.println(detail); Field name = cls.getDeclaredField("name"); // 2.创建对象 Object o = cls.newInstance(); // 3 通过字段的set方法设置 name.set(o, "娇娇"); System.out.println(o.toString()); } catch (ClassNotFoundException | NoSuchFieldException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } }

4、字段赋值

 方法// 获取所有的”公有字段” Field[] getFields() // 获取所有字段(私有、受保护、默认、公有) Field[] getDeclaredFields()

 举个栗子public class TestReflectUserField { public static void main(String[] args) { try { Class<?> cls = Class.forName("com.wener.reflect.demo1.User"); Field[] fields = cls.getFields(); for (Field field : fields) { System.out.println("类型: " + field.getType() + "方法名: " + field.getName()); } Field[] declaredFields = cls.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println("类型: " + declaredField.getType() + "方法名: " + declaredField.getName()); } } catch (ClassNotFoundException | NoSuchFieldException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } } }

3、获取所有成员字段

2、获取单个成员字段类的成员变量也是一个对象,它是java.lang.reflect.Field的一个对象,所以我们通过java.lang.reflect.Field里面封装的方法来获取这些信息并且操作这些属性1、说明四、属性操作

 cls.newInstance()方法返回的是一个泛型T,我们要强转成自定义类

 cls.newInstance()默认返回的是类的无参数构造对象

 被反射机制加载的类必须有无参数构造方法,否者运行会抛出异常

1.4、注意三、创建实例

 常用的是类的静态方法,

 getClass()的话一般在继承的时候用的比较多一点,比如Android里的注解框架

 .class 静态语法: 需要导入类的包,依赖太强,不导包就抛编译错误

“如何理解Java反射技术”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何理解Java反射技术

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何理解Java反射技术

本篇内容介绍了“如何理解Java反射技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、前期概要1、 什么是反射Java 反射机制在程序运
2023-06-02

如何在Java中应用反射技术

如何在Java中应用反射技术?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、反射概念Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象
2023-06-15

浅谈 Java 反射技术

反射 (Reflection) 是 Java 的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性。

Java反射技术怎么用

这篇文章主要为大家展示了“Java反射技术怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java反射技术怎么用”这篇文章吧。一、基本反射技术1.1 根据一个字符串得到一个类getClass
2023-06-25

如何理解反射

这篇文章主要介绍“如何理解反射”,在日常操作中,相信很多人在如何理解反射问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解反射”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!反射的思想及作用有反必有正,
2023-06-16

如何解析Java反射

今天就跟大家聊聊有关如何解析Java反射,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、什么是反射反射就是把Java类中的各个成分映射成一个个的Java对象。即在运行状态中,对于任
2023-06-25

java的反射技术详细介绍

本篇内容主要讲解“java的反射技术详细介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java的反射技术详细介绍”吧!反射的定义:审查元数据并收集关于它的类型信息的能力。下面介绍java的反
2023-06-17

java反射技术的使用场景

这篇文章主要介绍“java反射技术的使用场景”,在日常操作中,相信很多人在java反射技术的使用场景问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java反射技术的使用场景”的疑惑有所帮助!接下来,请跟着小编
2023-06-03

深入理解PHP反射技术:如何高效获取类信息?

PHP反射:获取类信息在PHP中,反射是一种强大的机制,它允许你动态地访问和修改对象的属性和方法。这在处理复杂、动态的数据结构时非常有用。然而,要有效地使用反射,你需要了解一些基础知识。本文将介绍如何使用PHP的反射机制来获取类的信息。首先,让我们了解一下什么是
深入理解PHP反射技术:如何高效获取类信息?
PHP2024-12-19

如何理解Java反射以及动态代理

这篇文章主要介绍“如何理解Java反射以及动态代理”,在日常操作中,相信很多人在如何理解Java反射以及动态代理问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解Java反射以及动态代理”的疑惑有所帮助!
2023-06-16

AJPFX反射及反射的应用该如何理解

本篇文章为大家展示了AJPFX反射及反射的应用该如何理解,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。怎么理解反射,反射的应用 反射就是把Java类中的各种成分映射成相应的Java类。
2023-06-02

DotNet开发之反射技术详解

反射技术是指在程序运行时动态地获取类型信息、访问对象成员(如属性、方法、字段等)以及调用对象的方法的能力。在许多编程语言中都有反射机制,包括 Java、C#、Python 等。

C# 基础:Reflection(反射)技术详解

反射是C#中一种强大的机制,它允许程序在运行时检查其元数据,并动态地访问和调用类型成员。通过反射,你可以实现更加灵活和动态的程序设计。

如何理解.NET的反射

这期内容当中小编将会给大家带来有关如何解.NET的反射,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。反射反射提供了封装程序集、模块和类型的对象(Type 类型)。可以使用反射动态创建类型的实例,将类型绑
2023-06-17

Java反射如何使用

这篇文章将为大家详细讲解有关Java反射如何使用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。反射相信刚接触Java的,第一句肯定会问什么是反射呢?反射有什么作用呢?为什么使用反射呢?首先反射是Java的
2023-06-25

Java反射机制怎么理解

本篇内容主要讲解“Java反射机制怎么理解”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java反射机制怎么理解”吧!1. 简介定义:Java语言中 一种动态(运行时)访问、检测 & 修改它本身
2023-06-03

Java反射机制深入理解

Java反射机制深入理解一.概念   反射就是把Java的各种成分映射成相应的Java类。Class类的构造方法是private,由JVM创建。反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录