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 登录数据库数据库…

map转字符串数组中 php_js将map转换成数组

linux中oops信息的调试及栈回溯【转】本文转载自:http://blog.csdn.net/kangear/article/details/8217329 ...linux 2&period;6 驱动笔记(一)本文作为linux 2.6 驱动笔记,记录环境搭建及linux基本内核模块编译加载. 环境搭建: 硬件:OK6410开发板 目标板操作系统:linux 2.6…

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

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

ecshop获取客户端操作系统

<?php /*** 获得客户端的操作系统** access private* return void*/ function get_os() {if (empty($_SERVER[HTTP_USER_AGENT])){return Unknown;}$agent strtolower($_SERVER[HTTP_USER_AGENT]);$os ;if (strpos($agent, win) ! false){if (strpos($agent, nt 5.1…

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

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

B站学习资源汇总

一个B站就足够解决绝大多数学习问题。 AI入门 1、Crash Course AI https://space.bilibili.com/276373762/channel/detail?cid=101907 课程介绍:该课程出自Crash Course,首发YouTube,单个视频时长均在10分钟左右。视频节奏非常好,语速偏快,适合下饭时间入门了解。主讲…

30个Java入门技巧和最佳实践

Java是最流行的编程语言之一-无论是Win应用程序&#xff0c;Web应用程序&#xff0c;移动&#xff0c;网络&#xff0c;消费电子产品&#xff0c;机顶盒设备&#xff0c;Java随处可见。 在Java上运行的设备超过30亿。 据甲骨文称 &#xff0c;正在使用50亿张Java卡。 超过900…

Postman使用详解

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

java double精确比较,Java float比double更精确?

Code:class Main {public static void main (String[] args) {System.out.print("float: ");System.out.println(1.35f-0.00026f);System.out.print("double: ");System.out.println(1.35-0.00026);}}Output:float: 1.34974double: 1.3497400000000002??…

《Bash 脚本教程》免费发布啦,开源!

一共写了 20 节&#xff0c;Bash 脚本编程的主要语法&#xff0c;都包括在内了&#xff0c;日常使用应该足够。也欢迎初学者使用这个教程&#xff0c;学习 Bash。 这个教程是开源的&#xff0c;你可以克隆它的代码仓库&#xff0c;放在本地&#xff0c;也可以提交 issue 和 pu…

linux脚本编程(shell)浅介 (转载)

linux脚本(shell)编程 啊&#xff0c;昨天上网看到一篇讲 linux/unix shell 的文章&#xff0c;想想自己最后写这东西也是一年前的事了&#xff0c;想想都快忘光了。 还是整理一下&#xff0c;做一次回顾&#xff0c;以后说不定还用得上&#xff1b;帖出来&#xff0c;方便第一…

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

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

java显示星期几_Java 使用日历显示星期几

import java.util.Calendar;/*nowjava.com 提 供*/public class Main {public static void main(String[] args) {//create Calendar instanceCalendar now Calendar.getInstance();System.out.println("Current date : " (now.get(Calendar.MONTH) 1) "-&qu…

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…

10个 IDEA 插件来解放你的双手

不知道喜欢IDEA的你装了没有? 1、GenerateAllSetter 实际的开发中,可能会经常为某个对象中多个属性进行 set 赋值,尽管可以用BeanUtil.copyProperties()方式批量赋值,但这种方式有一些弊端,存在属性值覆盖的问题,所以不少场景还是需要手动 set。如果一个对象属性太多 s…

哥斯拉Godzilla shell管理工具

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

使用Fabric8在Kubernetes中使用Camel和CDI

序幕 我最近在博客上发表了使用CDI注入Kubernetes服务的信息 。 在本文中&#xff0c;我将更进一步&#xff0c;将Apache Camel带入图片。 因此&#xff0c;我将使用Camel的CDI支持来连接我的组件和路由&#xff0c;以及Fabric8的CDI扩展来自动将Kubernetes服务注入到我的组件中…

sql双表查询java代码_原生sql 多表查询

Session session Session session super.getSession();session.flush();Connection con session.connection();String uid"";StringBuffer sql new StringBuffer();sql.append("select a.user_Id from user_info as a");//user用户表sql.append( left j…

写lua时需要注意的地方

条件语句判断时&#xff0c;只有false和nil会导致判断为假&#xff0c;其他的任何值都为真。 Lua 的字符串与编码无关&#xff1b; 它不关心字符串中具体内容。标准 Lua 使用 64 位整数和双精度&#xff08;64 位&#xff09;浮点数&#xff0c; 但你也可以把 Lua 编译成使用 3…

免费的人脸识别SDK(基于 Java 实现的人脸识别功能)

人脸识别技术是很复杂的&#xff0c;自己用Java手撕一个识别算法有点不切实际&#xff0c; 毕竟实力不允许我这么嚣张&#xff0c;还是借助三方的SDK吧&#xff01; 免费的人脸识别SDK&#xff1a; ArcSoft:&#xff0c;地址&#xff1a;https://ai.arcsoft.com.cn 基于 Jav…