java反射所需要了解的基本知识点

news2024/9/21 2:43:22

反射概述

反射:通过运行时操作元数据或对象,Java 可以灵活地操作运行时才能确定的信息指程序可以访问、检测和修改它本身状态或行为的一种能力。
其相关类在下面这个包里面:java.lang.reflect.*;

反射机制相关的重要的类:

  1. java.lang.Class 代表整个字节码。代表一个类型,代表整个类。
  2. java.lang.reflect.Method 代表字节码中的方法字节码。代表类中的方法。
  3. java.lang.reflect.Constructor 代表字节码中的构造方法字节码。代表类中的构造方法
  4. java.lang.reflect.Field 代表字节码中的属性字节码。代表类中的成员变量(静态变量+实例变量)

必须先获得Class才能获取Method、Constructor、Field。

Class文件(反射原理)

每个类都会产生一个对应的Class对象,一般保存在.class文件中,Class文件是一组以8字节为基础单位的二进制文件

Class对象仅在需要的时候才会加载,static初始化是在类加载时进行的

类加载时,类加载器首先会检查这个类的Class对象是否已被加载过,如果尚未加载,默认的类加载器就会根据类名查找对应的.class文件。

  • 虚拟机为每种类型管理一个独一无二的Class对象,每个类(型)都有一个Class对象
  • 运行程序时,Java虚拟机(JVM)首先检查所要加载的类对应的Class对象是否已经加载
  • 如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入
    在这里插入图片描述

特点

  1. java八个基本数据类型和关键字 void 也都对应一个 Class 对象

    • 八个基本数据类型:boolean、byte、char、short、int、long、float 和 double
  2. 每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象

  3. 一般某个类的Class对象被载入内存,它就用来创建这个类的所有对象。

该方法的执行会导致类加载,类加载时,静态代码块执行

推荐阅读:https://juejin.cn/post/6917050648563777544#comment

获取Class对象

Object类的getClass()方法

Person person = new Person();  
Class<?> class1 = person.getClass();
System.out.println( class1 );

运行结果

class com.app.Person

Class类的中静态forName()方法

Class<?> class2 = Class.forName("com.app.Person");
System.out.println( class2 );

运行结果

class com.app.Person

T.class

如果T是一个Java类型,那么T.class就代表了匹配的类对象。

Class<?> class3 = Person.class;
System.out.println( class3 );

运行结果

class com.app.Person

区别

使用”.class”来创建Class对象的引用时,不会自动初始化该Class对应类,使用forName()会自动初始化该Class对应类。

获取所有的方法:getMethods( )

//创建类
Class<?> class1 = Class.forName("com.app.Person");
//获取所有的公共的方法
Method[] methods = 	class1.getMethods() ;
for (Method method : methods) {
	System.out.println( method );
}

运行结果会将该方法的自定义的所有方法和父类Object的所有方法进行输出

获取某个方法:getMethod(“方法名”)

//创建类
Class<?> class1 = Class.forName("com.app.Person");
//获取所有的公共的方法
Method method = class1.getMethod("getName");
System.out.println( method );

运行结果会将该方法的getName方法输出

获取所有实现的接口:getInterfaces()

//创建类
Class<?> class1 = Class.forName("com.app.Person");
//获取所有的接口
Class<?>[] interS = class1.getInterfaces() ;
for (Class<?> class2 : interS ) {
	System.out.println( class2 );
}

获取父类:getSuperclass()

/创建类
Class<?> class1 = Class.forName("com.app.Person");
//获取父类
Class<?> superclass = class1.getSuperclass() ;
System.out.println( superclass );

获取所有具有public属性的构造函数:getConstructors()

返回所有具有public属性的构造函数数组

//创建类
Class<?> class1 = Class.forName("com.app.Person");
//获取所有的构造函数
Constructor<?>[] constructors = class1.getConstructors() ;
for (Constructor<?> constructor : constructors) {
	System.out.println( constructor );
}

获取所有的属性:getDeclaredFields();

获得某个类的所有申明的字段,即包括public、private和proteced,但是不包括父类的申明字段。

//创建类
Class<?> class1 = Class.forName("com.app.Person");
//取得本类的全部属性
Field[] field = class1.getDeclaredFields();
for (Field field2 : field) {
	System.out.println( field2 );
}

输出的结果也可以看出来其修饰符

获取公共属性:getFields();

getFields()获得某个类的所有的公共(public)的字段,包括父类。

//创建类
Class<?> class1 = Class.forName("com.app.Person");
//取得本类的全部属性
Field[] field = class1.getFields();
for (Field field2 : field) {
	System.out.println( field2 );
}

输出的结果也可以看出来其修饰符,但是只有public的内容

创建实例:newInstance()

//创建类
Class<?> class1 = Class.forName("com.app.Person");;
//创建实例化:相当于 new 了一个对象
Object object = class1.newInstance() ;
//向下转型
Person person = (Person) object ;

newInstance()和new的区别

区别1:

  1. 前者是使用类加载机制,后者是创建一个新类
  2. 为什么会有两种创建对象方式:
    • 要考虑到软件的可伸缩、可扩展和可重用等软件设计思想:Java中工厂模式经常使用newInstance()方法来创建对象

区别2:

  1. 从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载
  2. 但是使用newInstance()方法的时候,就必须保证:(两个步骤的正是Class的静态方法forName()所完成
    • 这个类已经加载;
    • 这个类已经连接了。

区别3:

  1. 在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。

一句话描述:

  1. newInstance: 弱类型。低效率。只能调用无参构造
  2. new: 强类型。相对高效。能调用任何public构造

执行某对象的某个方法:invoke()

作用:调用包装在当前Method对象中的方法。

原型:

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

参数解释:

  1. obj:实例化后的对象
  2. args:用于方法调用的参数

返回:根据obj和args调用的方法的返回值

方法说明

一:如果底层方法是静态的,那么可以忽略指定的 obj 参数,该参数可以为 null如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null

二:第一个参数是隐式参数(比如this,传进你要委托的对象);其余的可变参数提供了显式参数(Java SE 5.0以前没有可变参数,必须传递对象数组或者null);对于静态方法(属于类),第一个参数设置为null,作为隐式参数来传递

三:如果有返回类型,invoke方法将返回一个名义上的Object类型,实际类型由方法内部决定,所以还要进行强制类型转换

  1. 如果返回类型是基本类型,为了统一返回类型,将会返回其包装器类型,如下
    //省略显式参数,因为没有形参,不需要实参传入
    double s = (Double)m2.invoke(harry) 
    

举例

执行某个类的静态方法

nvoke的一个参数是null,因为这是静态方法,不需要借助实例运行

// 获取Integer.parseInt(String)方法,参数为String:
Method m = Integer.class.getMethod("parseInt", String.class);
// 调用该静态方法并获取结果:
Integer n = (Integer) m.invoke(null, "12345");
// 打印调用结果:
System.out.println(n);

执行某对象的方法

owner对象中带有参数args的method方法。返回值是Object,也既是该方法的返回值

public Object newInstance(String className, Object[] args) throws Exception { 
	//这个对象的Class
	Class ownerClass = owner.getClass();

	// 配置参数的Class数组,作为寻找Method的条件
	Class[] argsClass = new Class[args.length];  
	for (int i = 0, j = args.length; i < j; i++) {  
	    argsClass[i] = args[i].getClass();  
	}
	//过methodName和参数的argsClass(方法中的参数类型集合)数组得到要执行的Method。
	Method method = ownerClass.getMethod(methodName, argsClass); 
	// 执行该Method.invoke方法的参数是执行这个方法的对象owner,和参数数组args
	return method.invoke(owner, args);
} 

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

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

相关文章

图解系统:

1.硬件结构 1.1.存储器的层次关系 每个存储器只和相邻的一层存储器设备打交道&#xff0c;并且存储设备为了追求更快的速度&#xff0c;所需的材料成本必然也是更高&#xff0c;也正因为成本太高&#xff0c;所以 CPU 内部的寄存器、L1\L2\L3 Cache 只好用较小的容量&#xff…

node中文件的上传

node基于Express项目实现文件的上传 1、FormData对象&#xff1a;以对象的方式来表示页面中的表单&#xff0c;又称为表单对象。以key-value的方式来保存数据&#xff0c;XMLHttpRequest对象可以轻松的表单对象发送的服务器端&#xff1b; &#xff08;1&#xff09;使用构造…

图解LeetCode——1775. 通过最少操作次数使数组的和相等(难度:中等)

一、题目 给你两个长度可能不等的整数数组 nums1 和 nums2 。两个数组中的所有值都在 1 到 6 之间&#xff08;包含 1 和 6&#xff09;。 每次操作中&#xff0c;你可以选择 任意 数组中的任意一个整数&#xff0c;将它变成 1 到 6 之间 任意 的值&#xff08;包含 1 和 6&a…

【vim】Darcula 配色设置

因为本人一直习惯了用 Jetbrains 家的产品&#xff0c;而且一直独钟 Dracula 配色&#xff0c;因此想要在 Git Bash 中为 vim 配一款 Dracula 配色。本博客将详细介绍如何为 vim 配置暗系主题 Dracula。 一、安装 Dracula 在 Dracula 的官网其实已经给出了关于如何在 vim 中配…

夯实算法-课程表

题目&#xff1a;LeetCode 你这个学期必须选修 numCourses 门课程&#xff0c;记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示如果要学习课程 ai 则 必…

Linux系统编程5——Socket编程(网络通信)

文章目录前言一、套接字二、基础知识三、网络套接字函数3.1、struct sockaddr3.2、socket函数3.3、bind函数3.4、listen函数3.5、accept函数3.6、connect函数3.7、读取/发送数据函数3.8 客户端服务器通信demo四、select函数1、TCP状态简介2、端口复用2.1、setsockopt函数3、半关…

云之道知识付费v1.5.4小程序+前端(含pc付费插件)

内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 云之道知识付费v1.5.4小程序前端&#xff08;含pc付费插件&#xff09; 版本号&#xff1a;1.5.4 – 商用无限开 无需重新上传小程序 【修复】上一版本公众号版本打开白屏问题 版本号&a…

【C语言】函数三要素,变量作用域、生存周期、存储类型

目录 写在前面 一、函数的用法 1、声明 2、调用 3、定义 形参与实参类型不一致 形参与实参类型一致 函数值类型与返回值类型不一致 函数值类型与返回值类型一致 二、变量的作用域与生存周期 三、变量的储存类型&#xff08;auto,extern,static,register&#xff09;…

AI虚拟人千亿级市场来袭,景联文科技提供全方面数据采集标注服务

“AI虚拟人通过语音、文字、视觉的理解和生成&#xff0c;结合动作识别、环境感知等多种方式可与人进行互动。AI虚拟人中运用到的强大算法需要高质量标注数据不断对其进行优化训练&#xff0c;景联文科技提供全方面数据采集标注服务。” 11月18日&#xff0c;科大讯飞在第五届世…

行为型模式 - 访问者模式Visitor

学习而来&#xff0c;代码是自己敲的。也有些自己的理解在里边&#xff0c;有问题希望大家指出。 行为型模式&#xff0c;我之所以把他放到第一个&#xff0c;是因为它号称是GoF中最难的一个。 模式的定义与特点 在访问者模式中&#xff08;Visitor Pattern&#xff09;中&…

pandasGUI:一款开源的功能异常强大的数据可视化分析工具

在很早之前关于可视化的描述中&#xff0c;我们介绍过一款D-table的数据分析操作工具。和D-table的操作相似&#xff0c;还有一款pandasGUI的开源工具更加强势。 Pandasgui是一个开源的python模块&#xff0c;它为pandas创建了一个GUI界面&#xff0c;我们可以在其中使用panda…

Impact of Problem Decomposition on Cooperative Coevolution

0、论文背景 本文在CCVIL的基础上&#xff0c;讨论了问题的分解效果对于CC框架的影响。由于VIL本身是一项计算成本昂贵的任务&#xff0c;因此应该避免在VIL上花费过多的时间而对CCEA没有显著的好处。我们进行实证研究来解决三个密切相关的问题&#xff1a; 1)更好的问题分解会…

STC 51单片机58——旋转LED

STC11F LED部分&#xff1a; #include "STC11.h" #define u8 unsigned char #define u16 unsigned int //全亮 //u8 code Picture1[8]{0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f} ; //u8 code Picture2[8]{0xe7,0xdb,0xbd,0x7e,0x7e,0xbd,0xdb,0xe7}; //u8 code P…

阿里云的工程师又闯祸了,github上紧急修复

最近不少用户使用阿里云提供的测试用例出现了被删除了用户目录下的所有文件&#xff0c;项目地址是&#xff1a;https://github.com/aliyun/aliyun-clialiyun-cli/cli/completion_installer_test.goLines 87 to 99 in 550ccb6path : filepath.Join(u.HomeDir, ".bashrc&qu…

求知 | 聊聊Android资源加载那些事 - Resource的初始化

Hi,你好 &#x1f603; 引言 在上一篇&#xff0c;求知 | 聊聊Android资源加载的那些事 - 小试牛刀 中&#xff0c;我们通过探讨 Resource.getx() ,从而解释了相关方法的背后实现, 明白了那些我们日常调用方法的背后实现。 那么&#xff0c;不知道你有没有好奇 context.reso…

【蓝桥杯国赛真题07】python杨辉三角形 蓝桥杯青少年组python编程 蓝桥杯国赛真题解析

目录 python杨辉三角 一、题目要求 1、提示信息 2、编程实现 3、输入输出

蓝桥杯嵌入式Debug

文章目录前言一、Debug是什么二、如何调试1.重要调试按键介绍2.其他按键介绍三、监视变量窗口总结前言 这一篇文章是非常重要的&#xff0c;掌握了这篇文章有助于大家在比赛中快速找到错误。 一、Debug是什么 Debug是一种程序&#xff0c;一种调试工具&#xff0c;说白了就是…

Elasticsearch:如何在 Elastic Agents 中配置 Beats 来采集定制日志

在我之前的文章 “Observability&#xff1a;使用 Elastic Agent 来摄入日志及指标 - Elastic Stack 8.0”&#xff0c;我详细地描述了如何安装 Elasticsearch&#xff0c;Stack 及 Elastic Agents 来采集系统日志及指标。很多开发者可能会有疑问&#xff0c;在我们的实际使用中…

陈都灵《我们当打之年》热播《关索岭》上热搜,温州人爱望京卡牌

最近&#xff0c;电视连续剧《我们的当打之年》&#xff0c;正在各大卫视台热播&#xff0c;一起热起来的还有该剧主演陈都灵。说起主演陈都灵&#xff0c;她虽然不是正宗的电影学院科班出身&#xff0c;但是她的演技却透露着灵气&#xff0c;也给人以真实的感觉。 陈都灵无疑是…

[附源码]Python计算机毕业设计Django学习帮扶网站设计与实现

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…