Java反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。–百度百科
Java反射应用
如果想在跨网络的远程平台上创建和运行对象的能力,那么可以通过反射来实现,也就是远程方法调用(RMI),它允许一个Java程序将对象分布到多台机器上。例如可以将计算划分为许多小的计算单元,分布到空闲的机器上运行,从而提高运算速度。
反射在java EE框架(Spring、Struts、Hibernate等)中应用是非常广泛的,最大的用途就是支持以声明式的方法(在XML中)来描述应用的行为。例如Struts中XML中声明一个Action,框架的作者在开发框架时是不知道开发者会定义什么类,所以只能根据类名通过反射机制来创建对象。
<action name="Welcome" class="com.example.Welcome">
<result>/Welcome.jsp</result>
</action>
public class Welcome extends ExampleSupport {
public String execute() throws Exception {
......
return SUCCESS;
}
......
}
RTTI(Run-Time Type Information)和反射之间的区别在于,RTTI是编译器在编译时打开和检查.class文件。反射机制是在运行时打开和检查.class文件,.class 文件在编译时是不和获取的。
Java反射运用示例
普通的User实体类
import java.io.Serializable;
/**
* Created by yrs on 2017/7/13.
*/
public class User implements Serializable{
private int age;
private String name;
public User() {
}
public User(int age, String name){
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
输出类信息的工具类ReflectUtil
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
/**
* Created by yrs on 2017/7/13.
*/
public class ReflectUtil {
public void printClassInfo(Class<?> object) {
System.out.println("类名:" + object.getName());
Class<?> ParentClass = object.getSuperclass();
System.out.println("父类名:" + ParentClass.getName());
Class<?> interfaces[] = object.getInterfaces();
System.out.println("类实现的接口:");
for (Class<?> inter: interfaces) {
System.out.println(" " + inter.getName());
}
}
public void printClassConstructor(Class<?> object) {
Constructor<?> constructors[] = object.getConstructors();
System.out.println("类的构造器:");
for (Constructor<?> constructor: constructors) {
System.out.println(" 构造器名:" + constructor.getName());
System.out.println(" 构造器参数数量:" + constructor.getParameterCount());
System.out.print(" 参数类型:");
Class<?> types[] = constructor.getParameterTypes();
for (Class<?> type: types) {
System.out.print(" " + type.getName());
}
System.out.println();
}
}
public void printField(Class<?> object) {
//获取本类的字段,包括public、protect、private修饰的字段,但不包括父类的字段
Field[] fields = object.getDeclaredFields();
//获取类实现的接口或父类的字段,
//Field[] fields = object.getFields();
System.out.println("类的字段:");
for (Field field: fields) {
System.out.println(" " + field.getType().getName() + " " + field.getName());
}
}
public void printMethod(Class<?> object) {
//获取本类的方法,但不包括父类的方法
Method[] methods = object.getDeclaredMethods();
//获取类的所有方法,包括父类的方法
//Method[] methods = object.getMethods();
System.out.println("类的方法:");
for (Method method: methods) {
System.out.print(" " + method.getReturnType().getName() + " " + method.getName() + "(");
for (Parameter parameter: method.getParameters()) {
System.out.print(parameter.getType().getName() + " " + parameter.getName());
}
System.out.println(")");
}
}
}
测试类TestReflect
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* Created by yrs on 2017/7/13.
*/
public class TestReflect {
public static void main(String [] args) throws Exception {
//查看类相关的信息
Class<?> userClass = Class.forName("com.yrs.proxy.reflect.User");
ReflectUtil reflectUtil = new ReflectUtil();
reflectUtil.printClassInfo(userClass);
reflectUtil.printClassConstructor(userClass);
reflectUtil.printField(userClass);
reflectUtil.printMethod(userClass);
//实例化一个类的对象,并初始化
User user = (User)userClass.newInstance();
user.setName("ByrsH");
user.setAge(23);
System.out.println(user.getName() + " " + user.getAge());
//通过反射操作某个类的属性
Object object = userClass.newInstance();
Field field = userClass.getDeclaredField("age");
field.setAccessible(true);
field.set(object,18);
System.out.println(field.get(object));
//通过反射调用某个方法
Method methodSet = userClass.getDeclaredMethod("setName", String.class);
methodSet.setAccessible(true);
methodSet.invoke(object, "yrs");
Method methodGet = userClass.getDeclaredMethod("getName");
methodGet.setAccessible(true);
System.out.println(methodGet.invoke(object));
}
}
输出
类名:com.yrs.proxy.reflect.User
父类名:java.lang.Object
类实现的接口:
java.io.Serializable
类的构造器:
构造器名:com.yrs.proxy.reflect.User
构造器参数数量:0
参数类型:
构造器名:com.yrs.proxy.reflect.User
构造器参数数量:2
参数类型: int java.lang.String
类的字段:
int age
java.lang.String name
类的方法:
java.lang.String getName()
void setName(java.lang.String arg0)
void setAge(int arg0)
int getAge()
ByrsH 23
18
yrs