转!!java反射机制
Java 反射机制
基本概念
在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?
答案是肯定的。
这种动态获取类的信息以及动态调用对象的方法的功能来自于Java语言的反射(Reflection)机制。
Java反射机制主要提供了以下功能:
1.在运行时判断任意一个对象所属的类。
2.在运行时构造任意一个类的对象。
3.在运行时判断任意一个类所具有的成员变量和方法。
4.在运行时调用任意一个对象的方法。
Reflection是Java被视为动态(或准动态)语言的一个关键性质。
这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息。
包括其modifiers(诸如public、static等)、 superclass(例如Object)、实现了的 interfaces (例如Serializable)、也包括其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(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。
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()方法获取
// 这里用第二种方法,类名.class
Class<?> 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对象时需要指定名字。
转!!java反射机制的更多相关文章
- 第28章 java反射机制
java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...
- Java反射机制
Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射: 静态编译:在编译时确定类型,绑定对象,即通过 ...
- java基础知识(十一)java反射机制(上)
java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...
- java基础知识(十一)java反射机制(下)
1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...
- Java反射机制专题
·Java Reflection Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方 ...
- java反射机制深入详解
java反射机制深入详解 转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...
- Java反射机制DOME
Java反射机制 public class TestHibernate { @Test public void TestHb(){ try { Class cs = Class.forName(&qu ...
- 反射——Java反射机制
反射概述 什么是反射? ① 反射的概念是由Smith在1982年首次提出的,主要指程序可以访问.检测和修改它本身状态或行为的一种能力. ② JAVA反射机制是在运行状态中,对应任意一个类,都能 ...
- Java反射机制可以动态修改实例中final修饰的成员变量吗?
问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...
- Java反射机制学习与研究
Java反射机制:可以获取正在运行时的Java对象. 1.判断运行时对象对象所属的类. 2.判断运行时对象所具有的成员变量和方法. 3.还可以调用到private方法,改变private变量的值. S ...
随机推荐
- oracle 导出导入常见问题
oracle 导入导出常见有两种方法 EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用.EXPDP和IMPDP是服务端的工具程序,他们只能在ORACLE服务端使用,不能在客户 ...
- 数字证书私钥sign及验证
package com.epay.bank.test.encrypt; import java.io.FileInputStream; import java.security.KeyStore; i ...
- IOS自定义仪表盘
登录|注册 周海锋 的专栏 Objective-C/Cocos2d/Cocos2d-x/Php/JS 目录视图 摘要视图 订阅 2016软考项目经理实战班 学院周年礼-顶 ...
- 用InstallShield 打包工具 打 Win32 程序 (depends.exe 用看程序都依赖了哪些dll)
InstallShield 打包工具 1. 转载:http://blog.csdn.net/zhang_xinxiu/article/details/9099757 2. 转载:http://www. ...
- JavaScript的循环语句
JavaScript的循环语句 1.JavaScript的循环语句 (1)for循环语句 - 循环代码块一定的次数: (2)for/in循环语句 - 循环遍历对象的属性: (3)while循环语句 - ...
- SqlSever基础 order by之后再orderby,双重排序,对排序好的数据中再次进行排序
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...
- Web自定义协议,BS端启动CS端,
实例 1.准备CS项目,windows窗体应用程序,拖进来一个label控件来接受BS的参数,并显示,右击生成,复制该文件的bin目录下的exe,例如放在以下路径,例如C:\\simu\\下, 2.编 ...
- FZU 2146
Easy Game Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit St ...
- linux包的相关命令
apt-cache search package 搜索包 apt-cache show package 获取包的相关信息,如说明.大小.版本等 sudo apt-get install package ...
- 9.Parameters
1.Optional and Named Parameters calls these methods can optionally not specify some of the arguments ...