java-反射

news/2024/11/28 1:52:51/

反射

示例代码

import java.lang.reflect.*;
public class Example {public static void main(String[] args) throws Exception {// 获取 Class 对象Class<?> clazz = Class.forName("java.lang.String");// 获取类名、包名和修饰符String className = clazz.getName();String packageName = clazz.getPackage().getName();int modifiers = clazz.getModifiers();String modifierStr = Modifier.toString(modifiers);System.out.println("类名:" + className);System.out.println("包名:" + packageName);System.out.println("修饰符:" + modifierStr);// 获取构造器并创建对象Constructor<?> constructor = clazz.getConstructor(String.class);Object object = constructor.newInstance("Hello, world!");// 调用字符串方法,将字母转为大写Method method = clazz.getMethod("toUpperCase");String result = (String) method.invoke(object);System.out.println(result);}
}

反射的概念

反射机制指在程序运行过程中,对任意一个类都能获取其所有属性和方法,并且对任意一个对象都能调用其任意一个方法。这种动态获取类和对象的信息,以及动态调用对象的方法的功能被称为Java语言的反射机制。

反射(Reflection)是 Java 中非常重要且强大的一个特性,它允许程序在运行时动态地获取、检查和修改类的字段、方法、构造函数等成员,以及调用对象的方法,而不需要事先知道这些成员的名字或类型

通过反射,程序可以在运行时操作类的成员,而不必依赖于编译时的类型信息。这为我们编写灵活、扩展性强的代码提供了无限的可能性,可以更加方便地实现一些高级的功能和框架,如依赖注入、ORM 等。

在 Java 中,反射主要由以下三个类或接口组成:

  • Class 类:表示一个 Java 类型的类对象,包含了该类的所有信息,例如字段、方法、构造函数等成员。
  • Constructor 类:表示一个类的构造函数,可以用来创建该类的新实例。
  • Method 类:表示一个类的方法,可以用来调用该方法并获取方法的返回值。

反射的使用需要谨慎,因为它带来了一定的性能损失和安全风险。反射可以绕过访问权限的限制,因此不得不对其进行限制控制。反射还会使代码变得复杂和难以维护,同时也不符合面向对象编程的原则。因此,在实际开发中,应该根据具体需求和场景合理使用反射。

反射的步骤

(1)获取想要操作的类的Class对象,该Class对象是反射的核心,通过它可以调用类的任意方法。

  • 获取class对象的方法如下

    • 调用某个对象的getClass方法以获取该类对应的Class对象

      Person  p  =  new  Person();
      Class  clazz  =  p.getClass();
      
    • 调用某个类的class属性以获取该类对应的Class对象

      Class clazz = Person.class;
      
    • 调用Class类中的forName静态方法以获取该类对应的Class对象,这是最安全、性能也最好的方法

      Class clazz=Class.forName("fullClassPath"); //fullClassPath为类的包路径及名称
      

(2)调用Class对象所对应的类中定义的方法,这是反射的使用阶段。

(3)使用反射API来获取并调用类的属性和方法等信息。

示例代码

//1:获取Person类的Class对象
Class  clazz  =  Class.forName("hello.java.reflect.Persion");
//2:获取Person类的所有方法的信息
Method[]  method  =  clazz.getDeclaredMethods();
for(Method  m:method){System.out.println(m.toString());
}//3:获取Person类的所有成员的属性信息
Field[]  field  =  clazz.getDeclaredFields();
for(Field  f:field){System.out.println(f.toString());
}
//4:获取Person类的所有构造方法的信息
Constructor[]  constructor  =  clazz.getDeclaredConstructors();
for(Constructor  c:constructor){System.out.println(c.toString());
}

反射创建对象

创建对象的两种方式如下

  • 使用Class对象的newInstance方法创建该Class对象对应类的实例,这种方法要求该Class对象对应的类有默认的空构造器

  • 先使用Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance方法创建Class对象对应类的实例,通过这种方法可以选定构造方法创建实例。

示例代码

//1.1:获取Person类的Class对象
Class  clazz  =  Class.forName("hello.java.reflect.Persion");
//2.1:使用newInstane方法创建对象
Person  p  =  (Person)  clazz.newInstance();
//1.2:获取构造方法并创建对象
Constructor  c  =  clazz.getDeclaredConstructor(String.class, String.class, int.class);
//2.2:根据构造方法创建对象并设置属性
Person p1 = (Person) c.newInstance("李四", "男",20);

反射调用对象的方法

反射提供了 Method 类来表示一个类的方法,并允许我们在运行时动态地获取、调用和修改对象的方法。invoke() 方法可以用来调用指定对象的方法,并传入方法参数。

示例代码

//step 1:获取Persion类(hello.java.reflect.Persion)的Class对象
Class  clz  =  Class.forName("hello.java.reflect.Persion");
//step 2:获取Class对象中的setName方法
Method  method  =  clz.getMethod("setName", String.class);
//step 3:获取Constructor对象
Constructor  constructor  =  clz.getConstructor();
//step 4:根据Constructor定义对象
Object  object  =  constructor.newInstance(); //
//step 5:调用method的invoke方法,这里的method表示setName方法
//因此,相当于动态调用object对象的setName方法并传入alex参数
method.invoke(object,  "alex");

http://www.ppmy.cn/news/105223.html

相关文章

产品经理-产品驱动增长3-共识体验

公式&#xff1a;增长需求方案共识体验场域效率口碑流量&#xff0c;篇幅问题&#xff0c;这篇我们讲两个&#xff0c;分别是共识和体验 一、共识 前面我们研究了需求和方案&#xff0c;用介绍的方法已经为G公司和K公司的产品分别梳理了一条核心需求&#xff0c;并且还有三个方…

华为OD机试真题B卷 Java 实现【停车场车辆统计】,附详细解题思路

一、题目描述 特定大小的停车场&#xff0c;数组cars[]表示&#xff0c;其中1表示有车&#xff0c;0表示没车。 车辆大小不一&#xff0c;小车占一个车位&#xff08;长度1&#xff09;&#xff0c;货车占两个车位&#xff08;长度2&#xff09;&#xff0c;卡车占三个车位&a…

操作系统期末复习——课时十内存管理(一)

1、内存管理的基本原理和要求 1&#xff09;内存管理的定义 操作系统对内存的划分和动态分配就是内存管理的概念。 2&#xff09;内存管理的功能 &#xff08;1&#xff09;内存空间的分配和回收&#xff1a;由操作系统完成对主存的分配和回收&#xff0c;对编程人员透明。 &…

最热门高效的Node.JS开源第三方开发库和特点(持续更新......)

目录 1. Express 2. Socket.io 3. Mongoose 4. Passport 5. Async 6. PM2 7. Nodemailer 8. Request 9. Cheerio 10. Lodash 11. Bluebird 12. Winston 13. Socket.io-client 14. Node-sass 15. Moment 16. Gulp 17. Grunt 18. Chai 19. Sinon 20. Nodemon…

「SQL面试题库」 No_82 报告系统状态的连续日期

&#x1f345; 1、专栏介绍 「SQL面试题库」是由 不是西红柿 发起&#xff0c;全员免费参与的SQL学习活动。我每天发布1道SQL面试真题&#xff0c;从简单到困难&#xff0c;涵盖所有SQL知识点&#xff0c;我敢保证只要做完这100道题&#xff0c;不仅能轻松搞定面试&#xff0…

电子科技大学编译原理复习笔记(六):自上而下的语法分析

目录 前言 重点一览 引言 语法分析的功能 语法分析的分类 自上而下分析方法 回溯分析法 回溯分析法例子 方法 存在的问题 产生的原因 特点 解决缺陷 消除回溯&#xff08;重点&#xff09; 递归下降分析器 递归下降分析法 递归过程的构造 扩充BNF 改进的递…

20230529----重返学习-复合组件通信redux-redux源码-redux工程化开发-自定义hook

day-080-eighty-20230529-复合组件通信redux-redux源码-redux工程化开发-自定义hook 复合组件通信redux 要想实现复合组件通信&#xff0c;一般采用公共状态管理方案。常见的公共状态管理方案&#xff1a; 官方推荐的&#xff1a;redux。 redux react-redux redux-logger/r…

Java利用JOL工具分析对象分布

文章目录 对象的组成对象头[Header]实例数据[Instance Data]内存对齐[Padding] JOL工具分析对象Java项目引入依赖创建对象与结果分析创建简单无锁对象输出结果分析创建有属性的对象输出结果分析创建数组结果输出分析创建重量级锁对象输出结果分析 局限性 参考文章&#xff1a; …