- 浏览: 289777 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
SpringJava:
摘过来的
小心使用ArrayList和LinkedList -
jingjing0907:
我要成为第一个赞的人!呵呵,
小心使用ArrayList和LinkedList -
SpringJava:
cilendeng 写道应该用ConcurrentHashMa ...
实现单用户登陆session先进先出(session踢出) -
lingxiajiudu:
不错,完美解决我了的问题,赞一个。
子窗体给父窗体传值 javascript opener -
cilendeng:
应该用ConcurrentHashMap
实现单用户登陆session先进先出(session踢出)
Java提供的反射机制允许你在运行时动态加载类、查看类信息、生成对象或操作生成的对象。在整合式开发环境中所提供的方法提示或是泪查看工具,还
有象JSP中的JavaBean自动收集请求信息也使用到反射,而一些软件开发框架(Framework)也常见到反射机制的使用,以达到动态加载使用者
自定义类的目的。反射其实就是程序能够自检查自身信息。就像程序会照镜子反光看自己。
在程序中可以检查某个类中的方法属性等信息,并且能够动态调用。 这样可以写出很灵活的程序。 比如要把一个对象中的数据copy到另外一个对象中,规则是属性名相同就copy, 就可以用反射来做,不需要指定每个属性的名字,只要动态从类中取得信息, 再判断属性名是否相同即可。当然应用还有很多。 反射可以结合Java的字节码,使用ASM和cglib等库,还能动态生成类。 hibernate
的延迟载入,spring的AOP都是这么实现的
。反射给Java带来了一些动态性。不过虽然很好,但毕竟还是有一定局限性的。另外ASM,cglib使用还是不放便。因此一些纯动态语言现在是一个重要
发展趋势,比如ruby,python等,程序很容易动态生成。
那到底什么叫反射机制呢?
1. java
程序在运行时可以获得任何一个类的字节码信息,包括类的修饰符(public,static等),基类(超类,父类),实现的接口,字段和方法等信息。
2. java
程序在运行时可以根据字节码信息来创建该类的实例对象,改变对象的字段内容和调用对象方法.
我们把上面这种机制就叫反射技术。因为Java在真正需要使用一个类的时候才会加以加载,而不是在程序启动时就加载所有的类。大多数使用者都只
使用到应用程序的部分资源,在需要某些功能时才加载某些资源,可以让系统的资源运用更有效率(Java本身就是为了资源有限的小型设备而设计的,这样的考
虑是必然的)。
Java的反射机制是通过反射API来实现的,它允许程序在运行过程中取得任何一个已知名称的类的内部信息.反射API位于java.lang.reflect包中.主要包括以下几类:
1).Constructor类:用来描述一个类的构造方法
2).Field类:用来描述一个类的成员变量
3).Method类:用来描述一个类的方法.
4).Modifer类:用来描述类内各元素的修饰符
5).Array:用来对数组进行操作.
获取类的构造方法的
Constructor
对象
(
数组
)
Constructor[] getDeclaredConstructors();返回已加载类声明的所有的构造方法的Constructor对象数组.
Constructor getDeclaredConstructor(Class[] paramTypes);返回已加载类声明的指定构造方法的Constructor对象,paramTypes指定了参数类型.
Constructor[] getConstructors();返回已加载类声明的所有的public类型的构造方法的Constructor对象数组.
Constructor getConstructor(Class[] paramTypes);返回已加载类声明的指定的public类型的构造方法的Constructor对象,paramTypes指定了参数类型.
如果某个类中没有定义构造方法,第一个和第三个方法返回的数组中只有一个元素,就是缺省的构造方法;如果某个类中只定义了有参数的构造函数,而没有定义缺省构造函数,第一个和第三个方法返回的数组中不包含缺省的构造方法.
例子:
package
com.vincent.test;
import java.lang.reflect. * ;
public class DumpMethods {
public static void main(String[] args) {
try {
if (args.length < 1 ) {
System.out.println( " 请输入完整的类名: " );
return ;
}
Class strClass = Class.forName(args[ 0 ]);
// 检索带有指定参数的构造方法
Class[] strArgsClass = new Class[]{ byte []. class , String. class };
Constructor constructor = strClass.getConstructor(strArgsClass);
System.out.println( " Constructor: " + constructor.toString());
// 调用带有参数的构造方法创建实例对象object
byte [] bytes = " IT年薪 " .getBytes();
Object[] strArgs = new Object[]{bytes, " GBK " };
Object object = constructor.newInstance(strArgs);
System.out.println( " Object " + object.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.lang.reflect. * ;
public class DumpMethods {
public static void main(String[] args) {
try {
if (args.length < 1 ) {
System.out.println( " 请输入完整的类名: " );
return ;
}
Class strClass = Class.forName(args[ 0 ]);
// 检索带有指定参数的构造方法
Class[] strArgsClass = new Class[]{ byte []. class , String. class };
Constructor constructor = strClass.getConstructor(strArgsClass);
System.out.println( " Constructor: " + constructor.toString());
// 调用带有参数的构造方法创建实例对象object
byte [] bytes = " IT年薪 " .getBytes();
Object[] strArgs = new Object[]{bytes, " GBK " };
Object object = constructor.newInstance(strArgs);
System.out.println( " Object " + object.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Field[] getDeclaredFields():返回已加载类声明的所有成员变量的Field对象数组,不包括从父类继承的成员变量.
Field getDeclaredField(String name):返回已加载类声明的所有成员变量的Field对象,不包括从父类继承的成员变量,参数name指定成员变量的名称.
Field[] getFields():返回已加载类声明的所有public型的成员变量的Field对象数组,包括从父类继承的成员变量
Field getField(String name):返回已加载类声明的所有成员变量的Field对象,包括从父类继承的成员变量,参数name指定成员变量的名称.
例子:
package
com.vincent.test
import java.lang.reflect. * ;
public class ReflectTest {
private String name;
private String passwd;
public ReflectTest(String name,String passwd){
this .name = name;
this .passwd = passwd;
}
public static void main(String[] args) {
try {
ReflectTest rt = new ReflectTest( " Vincent " , " spring " );
fun(rt);
} catch (Exception e){
e.printStackTrace();
}
}
public static void fun(Object obj) throws Exception{
Field[] fields = obj.getClass().getDeclaredFields();
System.out.println( " 修改之前的值: " );
for (Field field:fields){
System.out.println(field.getName() + " = " + field.get(obj));
if (field.getType().equals(java.lang.String. class )){
// 必须设置为true才可以修改成员变量
field.setAccessible( true ); String org = (String)field.get(obj);
field.set(obj,org.replaceAll( " g " , " a " ));
}
}
System.out.println( " 修改之后的值: " );
for (Field field:fields){
System.out.println(field.getName() + " = " + field.get(obj));
}
}
}
import java.lang.reflect. * ;
public class ReflectTest {
private String name;
private String passwd;
public ReflectTest(String name,String passwd){
this .name = name;
this .passwd = passwd;
}
public static void main(String[] args) {
try {
ReflectTest rt = new ReflectTest( " Vincent " , " spring " );
fun(rt);
} catch (Exception e){
e.printStackTrace();
}
}
public static void fun(Object obj) throws Exception{
Field[] fields = obj.getClass().getDeclaredFields();
System.out.println( " 修改之前的值: " );
for (Field field:fields){
System.out.println(field.getName() + " = " + field.get(obj));
if (field.getType().equals(java.lang.String. class )){
// 必须设置为true才可以修改成员变量
field.setAccessible( true ); String org = (String)field.get(obj);
field.set(obj,org.replaceAll( " g " , " a " ));
}
}
System.out.println( " 修改之后的值: " );
for (Field field:fields){
System.out.println(field.getName() + " = " + field.get(obj));
}
}
}
获取类的方法的
Method
对象
(
数组
)
Method[] getDeclaredMethods():返回已加载类声明的所有方法的Method对象数组,不包括从父类继承的方法.
Method getDeclaredMethod(String name,Class[]
paramTypes):返回已加载类声明的所有方法的Method对象,不包括从父类继承的方法,参数name指定方法的名称,参数
paramTypes指定方法的参数类型.
Method[] getMethods():返回已加载类声明的所有方法的Method对象数组,包括从父类继承的方法.
Method getMethod(String name,Class[] paramTypes):返回已加载类声明的所有方法的Method对象,包括从父类继承的方法,参数name指定方法的名称,参数paramTypes指定方法的参数类型.
检索类的其他信息
int getModifiers():
返回已加载类的修饰符的整形标识值.
Package getPackage():返回已加载类的包名
Class getSuperclass():
返回已加载类的父类的Class实例.
Class [] getInterfaces():
返回已加载类实现的接口的Class对象数组.
boolean isInterface():返回已加载类是否是接口.
有时候我们说某个语言具有很强的动态性,有时候我们会区分动态和静态的不同技术与作法。我们朗朗上口动态绑定(dynamic
binding)、动态链接(dynamic linking)、动态加载(dynamic
loading)等。然而“动态”一词其实没有绝对而普遍适用的严格定义,有时候甚至像对象导向当初被导入编程领域一样,一人一把号,各吹各的调。
一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,答应改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。
尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。这个字的意思是“反射、映象、倒
影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称
的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods1。这种“看透
class”的能力(the ability of the program to examine
itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。
Java如何能够做出上述的动态特性呢?这是一个深远话题,本文对此只简单介绍一些概念。整个篇幅最主要还是介绍Reflection
APIs,也就是让读者知道如何探索class的结构、如何对某个“运行时才获知名称的class”生成一份实体、为其fields设值、调用其
methods。本文将谈到java.lang.Class,以及java.lang.reflect中的Method、Field、
ConstrUCtor等等classes。
“Class”class
众所周知Java有个Object class,是所有Java classes的继续根源,其内声明了数个应该在所有Java
class中被改写的methods:hashCode()、equals()、clone()、toString()、getClass()等。其中
getClass()返回一个Class object。
Class
class十分非凡。它和一般classes一样继续自Object,其实体用以表达Java程序运行时的classes和interfaces,也用来
表达enum、array、primitive Java types(boolean, byte, char, short, int,
long, float, double)以及要害词void。当一个class被加载,或当加载器(class
loader)的defineClass()被JVM调用,JVM 便自动产生一个Class
object。假如您想借由“修改Java标准库源码”来观察Class
object的实际生成时机(例如在Class的constructor内添加一个println()),不能够!因为Class并没有public
constructor(见图1)。本文最后我会拨一小块篇幅顺带谈谈Java标准库源码的改动办法。
Class是Reflection故事起源。针对任何您想探勘的class,唯有先为它产生一个Class object,接下来才能经由后者唤起为数十多个的Reflection APIs。这些APIs将在稍后的探险活动中一一亮相。
public final class Class<T> implements
java.io.Serializable,java.lang.reflect.GenericDeclaration,java.lang.reflect.Type,java.lang.reflect.AnnotatedElement
{
private Class() {}
public String toString() {
return ( isInterface() ? "interface " :
(isPrimitive() ? "" : "class "))
+ getName();
}
注重它的private empty ctor,意指不答应任何人经由编程方式产生Class object。是的,其object 只能由JVM 产生。
发表评论
-
栈的简单应用--单词反转
2014-07-03 16:00 695我们知道栈是一种先进后出,也就是后进先出的数据 ... -
java实现简单的栈
2014-07-01 11:56 643栈--只允许访问第一个数据项即:最后插入的数据。最简单的一句 ... -
小心使用ArrayList和LinkedList
2014-06-30 16:32 785ArrayList内部是使用可増长数组实现的,所以是用ge ... -
有趣的Java算法(3)
2014-06-30 16:29 681给定两个排序后的数组A和B,其中A的末端有足够的空间容纳B ... -
有趣的Java算法(2)
2014-06-30 16:29 1057今天分享一个"将一个整数的每位数分解并按逆序输 ... -
有趣的Java算法
2014-06-20 17:00 747题目及源码分析: /* * 今天在BBS里面看到这 ... -
java 值传递 引用传递
2010-12-17 23:11 2065java方法用的是值传递还是引用传递。你在blogjava上还 ... -
用java代码编写堆栈
2010-05-03 17:39 1233public class Stack { int[] ... -
几种读取属性文件的JAVA实现方式
2010-04-30 19:20 1178转载:http://darkranger.iteye.com/ ... -
Site
2010-04-30 19:20 966http://www.szikao.com/computer/ ... -
JAVA对XML的几种解析方式
2010-04-29 19:53 957对于XML介绍比较全面的还是IBM的专栏: ... -
集合与通用集合
2010-04-29 19:44 1430URL: http://www.ibm.com/develop ... -
HashMap 和TreeMap
2010-04-29 19:41 1276本文重点介绍HashMap。首先介绍一下什么是Map。在数组中 ... -
TreeMap和HashMap的问题
2010-04-29 19:39 2090在一次面试的过程 ... -
实现单用户登陆session先进先出(session踢出)
2010-04-29 19:33 9478首先在系统增加sessionListener 来监听sessi ... -
Java单态模式的实现
2010-04-29 19:23 15801.饿汉式:public class Sing ... -
请教java反射机制里可以调用私有方法吗?
2010-04-27 19:17 1626如题:请教java反射机制里可以调用私有方法吗? Metho ... -
利用java反射机制调用类的私有方法
2010-04-27 18:59 14171.将getInstance()方法设置为private ... -
String是原始数据类型还是引用数据类型
2010-04-26 19:22 1711请教各位高手,String是原始数据类型还是引用数据类型?谢谢 ... -
java中堆(heap)和堆栈(stack)有什么区别
2010-04-26 19:13 2195stack 和 heap 都是内存的 ...
相关推荐
java反射机制java反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制...
JAVA反射机制应用 JAVA反射机制是JAVA语言中的一种动态机制,它能够在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法。这种动态获取的信息以及动态...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部信息。通过Java反射机制,开发者可以在不知道具体类名的情况下创建对象,调用方法,访问和修改私有成员变量,以及...
Java反射机制是Java编程语言中的一个重要特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类集中在java.lang.reflect包下,包括Class、Constructor、Method和...
### Java反射机制深入理解 #### 一、反射机制概述 Java反射机制是一种强大的工具,它允许程序在运行时检查和操作任何类、方法、构造函数和字段等元素。这种能力对于构建灵活的应用程序和框架非常有用,特别是那些...
Java反射机制是Java语言提供的一种强大工具,它允许在程序运行时动态地获取类的信息以及对类的对象进行操作。在Java中,静态编译时类型检查确保了代码的稳定性,但有时我们需要在运行时根据需求动态地创建对象、调用...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部结构。通过反射,开发者可以动态地获取类的信息并调用其方法,创建对象,访问私有成员,甚至改变类的行为。在深入...
Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时获取和操作任何已知名称的类的内部信息。这一机制使得Java具备了一定的动态性,虽然在传统的分类中Java被视为静态类型语言。通过反射,开发者可以在...
Java 反射机制是 Java 语言中的一个重要特性,它允许程序在运行时动态地获取类的信息(如类名、属性、方法等)并调用对象的方法,甚至修改对象的状态。这一机制极大地增强了 Java 程序的灵活性和可扩展性,尤其是在...
这篇博文"Java反射机制学习(二)"可能深入探讨了如何利用反射进行动态类型处理、访问私有成员以及创建对象等核心概念。在这里,我们将详细讨论Java反射的基本用法及其在实际开发中的应用。 1. **什么是反射**: ...
java反射机制和动态代理的原理,熟悉反射机制和动态代理
### Java反射机制详解 #### 一、Java反射机制概述 Java反射机制是Java语言的一个重要特性,它允许程序在运行时获取类的信息并操作对象。Java反射机制的主要作用包括:获取类的所有属性和方法、构造动态实例、调用...
Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并操作类的对象。这种机制使得Java具有高度的灵活性和动态性,可以在编译时未知类的情况下进行类的加载、实例化、方法调用等操作...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、字段和方法的信息。这个特性使得Java具备了高度的灵活性,能够在运行时动态地发现和使用类的属性和方法,即使这些信息在编译时...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查并操作类、接口、字段和方法的信息,打破了通常编译时静态绑定的限制。通过反射,我们可以动态地创建对象,调用方法,访问和修改字段值,甚至...
### Java反射机制详解 #### 一、引言 在Java面试中,经常会出现与反射机制相关的题目。这是因为Java反射机制不仅是Java语言的一项重要特性,也是理解Java动态特性的关键所在。通过本文,我们将深入探讨Java反射...
java反射机制核心代码,小弟一直弄不明白,怎么通过反射来调用私有成员方法,看了这个后,你可以随心调用private方法,和属性,记得添加setAccessable(true),哦,要不还是不行,如:method.setAccessable(true);
Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并进行操作。通过反射,开发者可以在程序执行时发现并访问类的字段(fields)、方法(methods)以及构造器(constructors),...