Java反射机制通过JVM运行时动态获取类信息以及动态调用对象的方法。其实反射并不像我们想象的那么神秘,复杂。它通过java.lang.Class以及java.lang.reflect包的API实现的反射功能。我们在Spring AOP,JDBC数据库加载驱动都有用到反射机制。下面通过几段代码示例看看reflection究竟是如何工作的。
package com.me.reflection;
import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[]) {
try {
Class c = Class.forName("java.lang.String"]);//1
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
} catch (Throwable e) {
System.err.println(e);
}
}
}
大家对代码1处蛮眼熟吧,没错,在JDBC数据库加载驱动中用到了。这个程序使用 Class.forName 载入指定的类,然后调用 getDeclaredMethods 来获取这个类中定义了的方法列表。java.lang.reflect.Method是用来描述某个类中单个方法的一个类。
总结:获得指定类的方式有(1)Class.forName("") (2).class 如int.class (3)包装类.TYPE 如:Integer.TYPE
package com.me.reflection;
import java.lang.reflect.*;
public class MethodDemo {
private int f1(Object p, int x) throws NullPointerException {
if (p == null)
throw new NullPointerException();
return x;
}
public static void main(String args[]) {
try {
Class cls = Class.forName("com.me.reflection.MethodDemo");
//获得指定类的所有方法。通过getMethods()返回指定类所有公共方法
Method methlist[] = cls.getDeclaredMethods();
for (int i = 0; i < methlist.length; i++) {
Method m = methlist[i];
System.out.println("name = " + m.getName());
System.out.println("decl class = " + m.getDeclaringClass());
//获得每个方法的参数类型类表数组
Class pvec[] = m.getParameterTypes();
for (int j = 0; j < pvec.length; j++)
System.out.println("param #" + j + " " + pvec[j]);
}
} catch (Throwable e) {
System.err.println(e);
}
}
}
这个程序首先取得 MethodDemo类的描述,然后调用 getDeclaredMethods 来获取一系列的 Method 对象,它们分别描述了定义在类中的每一个方法,包括 public、protected package和private方法等。如果你在程序中使用getMethods来代替getDeclaredMethods,你还能获得继承来的各个方法的信息。
package com.me.reflection;
import java.lang.reflect.*;
public class ConstructorDemo {
public ConstructorDemo () {
}
protected ConstructorDemo (int i, double d) {
}
public static void main(String args[]) {
try {
Class cls = Class.forName("com.me.reflection.ConstructorDemo");
//获得指定类的所有构造方法。通过getConstructors()返回指定类所有公共构造方法
Constructor ctorlist[] = cls.getDeclaredConstructors();
for (int i = 0; i < ctorlist.length; i++) {
Constructor ct = ctorlist[i];
System.out.println("name = " + ct.getName());
System.out.println("decl class = " + ct.getDeclaringClass());
//获得每种构造方法的参数类型类表数组
Class pvec[] = ct.getParameterTypes();
for (int j = 0; j < pvec.length; j++)
System.out.println("param #" + j + " " + pvec[j]);
}
} catch (Throwable e) {
System.err.println(e);
}
}
}
获取类构造器的用法与上述获取方法的用法类似。
package com.me.reflection;
import java.lang.reflect.*;
public class FieldDemo{
private double d;
public static final int i = 37;
String s = "testing";
public static void main(String args[]) {
try {
Class cls = Class.forName("com.me.reflection.FieldDemo");
Field fieldlist[] = cls.getDeclaredFields();
for (int i = 0; i < fieldlist.length; i++) {
Field fld = fieldlist[i];
System.out.println("name = " + fld.getName());
System.out.println("decl class = " + fld.getDeclaringClass());
System.out.println("type = " + fld.getType());
int mod = fld.getModifiers();
System.out.println("modifiers = " + Modifier.toString(mod));
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
}
}
这个例子和前面那个例子非常相似。例中使用了一个新东西
Modifier,它也是一个 reflection 类,用来描述字段成员的修饰语,如“private int”。这些修饰语自身由整数描述,而且使用 Modifier.toString 来返回以“官方”顺序排列的字符串描述 (如“static”在“final”之前)。
以上显示了通过reflection获得类信息的这种用法。那么如何动态创建类对象,调用方法呢
package com.me.reflection;
import java.lang.reflect.*;
public class ReflectionApp {
public ReflectionApp(){}
public ReflectionApp(int a,int b){
System.out.println("a = " + a + " b = " + b);
}
public int add(int a, int b) {
return a + b;
}
public static void main(String args[]) {
try {
Class cls = Class.forName("com.me.reflection.ReflectionApp");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
//创建类对象 如果指定类只有默认构造方法,我们可通过cls.newInstance()直接生成类对象,只有Class和Constructor这两个类可以直接生成类对象
Constructor ct = cls.getConstructor(partypes);
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
[color=red]//注意:Class#getConstructor和Constructor#newInstance方法参数类型是一致的[/color]
ReflectionApp ra = (ReflectionApp)ct.newInstance(arglist);
//获得指定类指定方法
Method meth = cls.getMethod("add", partypes);
//动态调用类方法:通过invoke(指定类对象,方法参数类型列表)方法
Object retobj = meth.invoke(ra, arglist);
Integer retval = (Integer) retobj;
System.out.println(retval.intValue());
} catch (Throwable e) {
System.err.println(e);
}
}
}
很多同学认为创建一个对象调用一下方法怎么写这么麻烦,但是使用这种方法可以在程序运行时动态地创建对象,动态调用方法,而不是在编译的时候创建对象,这一点非常有价值。大家可以参照Java API研究下如何改变属性值等其他功能。动态创建数组将在以后的文章写到。
分享到:
相关推荐
java反射机制+代码示例.rar 看一遍我就明白这是怎么一回事了~~
讲述java 反射机制的典型示例,通过学习应该能很好的掌握
Java反射机制学习总结,附带程序示例。
Java反射机制:反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能。
主要介绍了java反射机制示例,需要的朋友可以参考下
java中的反射机制的示例,反射在java的开发过程中是经常用到的,会使你的代码更灵活,更优秀.
反射就是加载类,并解剖出类的各个组成部分,下面介绍了java反射机制示例,大家参考使用吧
1、本文详细描述了java反射机制的作用及使用方法。 2、通过详细示例,让读者更直观地阅读,更清晰的理解。 3、示例代码可直接复制,编译后可直接运行。 4、根据示例以及运行结果,让读者加强记忆及理解。
主要介绍了JAVA反射机制,包括了Java反射机制的各种应用技巧,非常具有实用价值,需要的朋友可以参考下
java反射API的详细说明及调用的示例说明等
主要介绍了java反射机制实战示例,需要的朋友可以参考下
Java反射机制与Class类1.Java反射机制1.1 反射机制是什么1.2 反射的应用场合1.3 反射的常用类1.4 反射使用步骤2. Class类2.1 常用方法和示例2.2 获取Class对象的 3 种方法2.3 反射创建对象的 2 种方法3. 工厂设计...
《Java语言的反射机制.pdf》资料书,示例源代码JAVA+Spring,初学java反射者可以看看
代码范例列表 第1章 ... useArray2.java 用反射机制使用数组示例2 第10章 示例描述:本章学习泛型。 demoBounds.java 演示有界类型 demoForceChange.java 演示强制类型转换 demoGeneric.java ...
介绍JAVA反射机制,及代理模式,展示相应示例.
获得类名 判断是接口还是类 获得修饰符 final public 获得父类 获得接口 获得字段 (某个,所有) 获得字段类型 获得私有字段 获得构造 (某个,所有) 获得构造参数 获得方法 获得返回类型 ...有非常详细的注释
尽管在这样得定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关的机制:反射机制 (Reflection)。 什么是反射? 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改...
里面有很多我做项目时候总结的ppt文档和示例。 包括很多一些Java机制用法和一下常用技术 希望大家喜欢
主要介绍了Java基于反射机制实现全部注解获取的方法,结合实例形式分析了java反射机制获取注解的具体实现方法与操作注意事项,需要的朋友可以参考下
这段代码实现了一个简单的日志记录器LoggerUtil,其中使用了Java的反射机制。在类的构造方法中,创建了一个...这个简单的示例代码展示了如何使用Java反射来实现一个日志记录器,方便了对程序运行时信息的记录和管理。