Java反射(Reflection)

基本概念

  在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?

  答案是肯定的。

  这种动态获取类的信息以及动态调用对象的方法的功能来自于Java语言的反射(Reflection)机制

  

  Java反射机制主要提供了以下功能:

  1.在运行时判断任意一个对象所属的类。

  2.在运行时构造任意一个类的对象

  3.在运行时判断任意一个类所具有的成员变量和方法。

  4.在运行时调用任意一个对象的方法

      5.在运行时设定任意一个对象的属性值

  Reflection是Java被视为动态(或准动态)语言的一个关键性质。

  这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息。

  包括其modifiers(诸如public、static等)、 superclass(例如Object)、实现了的 interfaces (例如Serializable)、也包括其constuctors,fields和methods的所有信息,并可于运行时改变fields内容或调用methods。

 

动态语言

  动态语言的定义“程序运行时,允许改变程序结构或者变量类型,这种语言称为动态语言”。

  从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。

  尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。这个字的意思是:反射、映像、倒影,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。

  换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

  这种“看透”class的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflectionintrospection是常被并提的两个术语。

 

Java Reflection API简介

  在JDK中,主要由以下类来实现Java反射机制,这些类(除了第一个)都位于java.lang.reflect包中

  Class:代表一个类,位于java.lang包下。

  Field:代表类的成员变量(成员变量也称为类的属性)。

  Method:代表类的方法。

  Constructor:代表类的构造方法。

  Array:提供了动态创建数组,以及访问数组的元素的静态方法。

 

Class对象

  要想使用反射,首先需要获得待操作的类所对应的Class对象。

  Java中,无论生成某个类的多少个对象,这些对象都会对应于同一个Class对象。

  这个Class对象是由JVM生成的,通过它能够获悉整个类的结构。

 

  常用的获取Class对象的3种方式:

  1.使用Class类的静态方法例如:  

Class.forName("java.lang.String");

 

  2.使用类的.class语法如:

String.class;

 

  3.使用对象的getClass()方法。如:

String str = "aa";
Class<?> classType1 = str.getClass();

 

  getClass()方法定义在Object类中,不是静态方法,需要通过对象来调用,并且它声明为final,表明不能被子类所覆写。

  直接print所获得的Class对象classType会输出:

    class 完整类名

  如果调用该Class对象的getName()方法,则输出完整类名,不加class。

 

例程1:获取方法

  例程DumpMethods类演示了Reflection API的基本作用,它读取命令行参数指定的类名,然后打印这个类所具有的方法信息。 

复制代码
import java.lang.reflect.Method;public class DumpMethods
{public static void main(String[] args) throws Exception //在方法后加上这句,异常就消失了{//获得字符串所标识的类的class对象Class<?> classType = Class.forName("java.lang.String");//在此处传入字符串指定类名,所以参数获取可以是一个运行期的行为,可以用args[0]//返回class对象所对应的类或接口中,所声明的所有方法的数组(包括私有方法)Method[] methods = classType.getDeclaredMethods();//遍历输出所有方法声明for(Method method : methods){System.out.println(method);}}}
复制代码

 

 

例程2:通过反射调用方法

  通过反射调用方法。详情见代码及注释:

 

复制代码
import java.lang.reflect.Method;public class InvokeTester
{public int add(int param1, int param2){return param1 + param2;}public String echo(String message){return "Hello: " + message;}public static void main(String[] args) throws Exception{// 以前的常规执行手段InvokeTester tester = new InvokeTester();System.out.println(tester.add(1, 2));System.out.println(tester.echo("Tom"));System.out.println("---------------------------");// 通过反射的方式// 第一步,获取Class对象// 前面用的方法是:Class.forName()方法获取// 这里用第二种方法,类名.classClass<?> classType = InvokeTester.class;// 生成新的对象:用newInstance()方法Object invokeTester = classType.newInstance();System.out.println(invokeTester instanceof InvokeTester); // 输出true// 通过反射调用方法// 首先需要获得与该方法对应的Method对象Method addMethod = classType.getMethod("add", new Class[] { int.class,int.class });// 第一个参数是方法名,第二个参数是这个方法所需要的参数的Class对象的数组// 调用目标方法Object result = addMethod.invoke(invokeTester, new Object[] { 1, 2 });System.out.println(result); // 此时result是Integer类型//调用第二个方法Method echoMethod = classType.getDeclaredMethod("echo", new Class[]{String.class});Object result2 = echoMethod.invoke(invokeTester, new Object[]{"Tom"});System.out.println(result2);}
}
复制代码

 

 

生成对象

 

  若想通过类的不带参数的构造方法来生成对象,我们有两种方式:

  1.先获得Class对象,然后通过该Class对象的newInstance()方法直接生成即可:

     Class<?> classType = String.class;Object obj = classType.newInstance();

 

  2.先获得Class对象,然后通过该对象获得对应的Constructor对象,再通过该Constructor对象的newInstance()方法生成

  (其中Customer是一个自定义的类,有一个无参数的构造方法,也有带参数的构造方法):

复制代码
    Class<?> classType = Customer.class;// 获得Constructor对象,此处获取第一个无参数的构造方法的Constructor cons = classType.getConstructor(new Class[] {});// 通过构造方法来生成一个对象Object obj = cons.newInstance(new Object[] {});
复制代码

 

  若想通过类的带参数的构造方法生成对象,只能使用下面这一种方式:

  (Customer为一个自定义的类,有无参数的构造方法,也有一个带参数的构造方法,传入字符串和整型)

    Class<?> classType = Customer.class;Constructor cons2 = classType.getConstructor(new Class[] {String.class, int.class});Object obj2 = cons2.newInstance(new Object[] {"ZhangSan",20});

  可以看出调用构造方法生成对象的方法和调用一般方法的类似,不同的是从Class对象获取Constructor对象时不需要指定名字,而获取Method对象时需要指定名字。

 

     原文转至与http://www.cnblogs.com/mengdd/archive/2013/01/26/2877972.html

转载于:https://www.cnblogs.com/onlysun/p/4530451.html

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

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

相关文章

超详细的MySQL三万字总结

文章目录 MySQL基础数据库的介绍数据库概述数据的存储方式数据库的概念常见数据库排行榜 数据库的安装与卸载数据库的安装数据库的卸载 数据库服务的启动与登录Windows 服务方式启动DOS 命令方式启动控制台连接数据库SQLyog 图形化工具——客户端使用 SQLyog 登录数据库数据库…

你要的能做出炫酷图表的网站来啦

不需要多高深的技术&#xff0c;也不需要多长时间&#xff0c;分分钟让小白都能做出超好看的图表~ 1.DataV DataV 是阿里云出品的在线可视化工具&#xff0c;可以将超多数据&#xff0c;放在一块大屏上 2.网易有数 网易有数的特点是&#xff0c;编辑页面自由度非常高&#x…

求有向图中两点最短距离java_算法题解:求有向图中的最短路径(JAVA+DFS算法实现)...

求有向图中的最短路径(JAVADFS算法实现)问题描述给定一个有向图&#xff0c;如下图所示&#xff0c;求从1号顶点到5号顶点的最短路径。输入数据格式为第一行输入顶点数和边数&#xff0c;从第二行开始每一行输入3个整数&#xff0c;分别代表连接顶点的边和权重。例如&#xff1…

Postman使用详解

一、Postman背景介绍 用户在开发或者调试网络程序或者是网页B/S模式的程序的时候是需要一些方法来跟踪网页请求的&#xff0c;用户可以使用一些网络的监视工具比如著名的Firebug等网页调试工具。今天给大家介绍的这款网页调试工具不仅可以调试简单的css、html、脚本等简单的网…

postman插件下载安装教程(详细)

一、前言 postman是一款强大网页接口调试工具&#xff0c;我们在平时开发过程中经常会使用到&#xff0c;一般使用最多的是postman的客户端&#xff0c;实际上postman在谷歌浏览器上也提供了插件&#xff0c;可以不必要安装客户端进行接口测试工作。 建议更新到最新谷歌浏览器&…

SharePoint 2013 workflow cannot start automatically when you logged in site as a system account

I have created one simple workflow on custom list using SharePoint designer 2013.While designing workflow, I have unchecked the “Allow this workflow to be manually started” and select rest two options like “Start workflow automatically when an item is c…

哥斯拉Godzilla shell管理工具

各大厂商的waf不断&#xff0c;在静态查杀、流量通信等方面对webshell进行拦截&#xff0c;众红队急需一款优秀的权限管理工具&#xff0c;冰蝎3.0的发布可能缓解了流量加密的困境&#xff0c;但是冰蝎3.0的bug众多&#xff0c;很多朋友甚至连不上冰蝎的shell&#xff0c; 于是…

git信息泄露漏洞

git信息泄露漏洞 当前大量开发人员使用git进行版本控制&#xff0c;对站点自动部署。如果配置不当&#xff0c;可能会将.git文件夹直接部署到线上环境。这就引起了git泄露漏洞。 危害 攻击者可以利用该漏洞下载git文件夹里的所有内容。如果文件夹内有敏感信息比如站点源码、数据…

功能项目拼图将Java 9引入

因此&#xff0c;拼图项目...我们已经对此颇为了解&#xff0c;但尚未看到计划如何兑现其承诺的细节。 这篇文章将精确地做到这一点&#xff0c;并介绍项目的核心概念和功能。 系列 这篇文章是正在进行的有关拼图项目系列的一部分。 按照推荐的顺序&#xff08;不同于发布顺序…

2021Kali -- 木马免杀制作

​知道为什么梦里的人都看不清脸么&#xff1f;因为怕你当真。。。 ---- 网易云热评 一、通过MSF生成shellcode 1、启动MSF&#xff0c;演示版本是6.0.36 2、通过msfvenom生成相关代码 msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 12 -b \x00 l…

OpenCV与YOLO学习与研究指南

引言 OpenCV是一个开源的计算机视觉和机器学习软件库&#xff0c;而YOLO&#xff08;You Only Look Once&#xff09;是一个流行的实时对象检测系统。对于大学生和初学者而言&#xff0c;掌握这两项技术将大大提升他们在图像处理和机器视觉领域的能力。 基础知识储备 在深入…

目录爆破工具 -- dirsearch

我记得&#xff0c;以前总会和你聊的很晚很晚&#xff0c;现在我们不再说话了&#xff0c;我还是会熬夜&#xff0c;但我想&#xff0c;不如从今天开始早点睡吧。。。 一、环境&#xff1a;Kali2020.01、Python3.0 二、安装过程&#xff1a; 1、复制dirsearch到本地安装包 gi…

java coin介绍_代码示例中的Java 7:Project Coin

java coin介绍该博客通过代码示例介绍了一些新的Java 7功能&#xff0c;这些项目在Project Coin一词下进行了概述。 Project Coin的目标是向JDK 7添加一组小的语言更改。这些更改确实简化了Java语言语法。 更少的打字&#xff0c;更简洁的代码&#xff0c;愉悦的开发人员&#…

在Java中实现过滤器和面包店锁

为了了解锁的工作方式&#xff0c;实现自定义锁是一个好方法。 这篇文章将展示如何在Java上实现Filter和Bakery锁&#xff08;自旋锁&#xff09;&#xff0c;并将它们的性能与Java的ReentrantLock进行比较。 过滤器锁和面包房锁满足互斥并且也是无饥饿算法&#xff0c;面包房锁…

Burpsuite工具的证书安装

Burpsuite工具的证书安装 Bursuite作为一款可以用来挖掘各种各样的WEB安全漏洞工具&#xff0c;在web安全渗透方面经常会使用到&#xff0c;可以用Bursuite进行对数据的抓包&#xff0c;其不安装证书时只能抓取http的包&#xff0c;安装证书就可以抓取https包&#xff0c;并分析…

物资申请php,php学生捐赠物品管理系统

捐赠物品管理系统采用php编程语言开发,mysql作为后台数据库支持,运行在wamp,appserv等集成环境上.为了方便学生捐赠物品&#xff0c;让更多的贫困人民得到更多的帮助&#xff0c;开发一套校园物品捐赠系统是十分必要的。而且可以培养学生的社会责任感&#xff0c;让他们更加富有…

哥斯拉Webshell

一&#xff0e;启动 命令&#xff1a;java -jar Godzilla-V2.96.jar 启动时同目录会生成data.db数据库存放数据 启动成功界面如下 二&#xff0e;使用&#xff08;在本机实测&#xff09; 这里演示jsp文件进行连接&#xff08;需要提前配置好jsp环境&#xff09; 1.点击管…

一次线上ctf的网络协议分析

拿到的是两个东西 我们先看secret.log 很多乱码但是有一串16进制数 把这段复制下来&#xff0c;我们放到HxD看 点击新建&#xff0c;直接粘贴 发现不对&#xff0c;观察头部&#xff0c;发现少了一个数&#xff08;5&#xff09; 因为加上5就是一个rar头部 即 导出来&…

Hibernate Collection Cache如何工作

介绍 之前&#xff0c;我描述了Hibernate用于存储实体的二级缓存条目结构。 除了实体&#xff0c;Hibernate还可以存储实体关联&#xff0c;本文将阐明集合缓存的内部工作原理。 领域模型 对于即将进行的测试&#xff0c;我们将使用以下实体模型&#xff1a; 存储库具有一组C…

模拟服务器和客户端交互的python脚本

脚本&#xff1a; 模拟服务器和客户端交互&#xff1a; import argparse, socket from datetime import datetimeIP "127.0.0.1" CODING "utf8" MAX_BYTES 65535 # UDP最大长度def server(port): # port&#xff1a;端口号sock socket.socket(socke…