java反射机制
所以我们就不用麻烦了。如果我们拿到一个类的类型信息,就可以利用反射获取其各种成员以及方法了。(注:Class 从JDK1.5版本后就开始更多为泛型服务了)那么我们怎么拿到一个类型的信息呢?假设我们有一个Role类:
package yui;
/**
* A base class having some attributes and methods
* @author Octobershiner
* @since 2012 3 17
*
* */
public class Role
private String name;
private String type;
// Constructors
public Role(){
System.out.println("Constructor Role() is invoking");
}
//私有构造器
private Role(String name){
this.name = name;
System.out.println("Constructor Role(String name) is invoking.");
}
//get and set method
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
//override the toString method to show the class
@Override
public String toString(){
return "This is a role called " this.name;
}
}
在没有对象实例的时候,主要有两种办法。
//获得类类型的两种方式
Class cls1 = Role.class;
Class cls2 = Class.forName("yui.Role");
注意第二种方式中,forName中的参数一定是完整的类名(包名 类名),并且这个方法需要捕获异常。现在得到cls1就可以创建一个Role类的实例了,利用Class的newInstance方法相当于调用类的默认的构造器
Object o = cls1.newInstance(); //创建一个实例
//Object o1 = new Role(); //与上面的方法等价
这样就创建了一个对象,缺点是我们只能利用默认构造函数,因为Class的newInstance是不接受参数的,后面会讲到可接受参数的newInstance,第二,如果类的构造函数是private的,比如Class,我们仍旧不能实例化其对象
获取类的构造器
首先介绍一下Constructor类,这个类用来封装反射得到的构造器,Class有四个方法来获得Constructor对象
- public Constructor<?>[] getConstructors() 返回类中所有的public构造器集合,默认构造器的下标为0
- public Constructor<T> getConstructor(Class<?>... parameterTypes) 返回指定public构造器,参数为构造器参数类型集合
- public Constructor<?>[] getDeclaredConstructors() 返回类中所有的构造器,包括私有
- public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回任意指定的构造器
/**
2 * 获取构造方法Constructor
3 * getConstructor() only for public
4 * getDeclaredConstructor() global access all
5 *
6 * */
7
8 //指定参数列表获取特定的方法
9 Constructor con = cls1.getDeclaredConstructor(new Class[]{String.class});
10 con.setAccessible(true); //设置可访问的权限
11 Object obj = con.newInstance(new Object[]{"liyang"});
12 System.out.println(obj); //打印一下这个对象的信息
13
14 //获取所有的构造方法集合
15 Constructor con1[] = cls1.getDeclaredConstructors();
16 con1[1].setAccessible(true);
17 Object obj1 = con1[1].newInstance(new Object[]{"tom"});
18 System.out.println(obj1);
- public Field getDeclaredField(String name) 获取任意指定名字的成员
- public Field[] getDeclaredFields() 获取所有的成员变量
- public Field getField(String name) 获取任意public成员变量
- public Field[] getFields() 获取所有的public成员变量
- public Method[] getMethods() 获取所有的共有方法的集合
- public Method getMethod(String name,Class<?>... parameterTypes) 获取指定公有方法 参数1:方法名 参数2:参数类型集合
- public Method[] getDeclaredMethods() 获取所有的方法
- public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 获取任意指定方法
package org.curry.tool; import java.lang.reflect.Method;
public class InvokeMethods {
public static void main(String[] args) {
Employee emp = new Employee();
Class cl = emp.getClass();
//是Class,而不是class
// /getClass获得emp对象所属的类型的对象,Class就是类的类
// /Class是专门用来描述类的类,比如描述某个类有那些字段,
// /方法,构造器等等!
try {
// /getMethod方法第一个参数指定一个需要调用的方法名称
// /这里是Employee类的setAge方法,第二个参数是需要调用
// 方法的参数类型列表,是参数类型!如无参数可以指定null
// /该方法返回一个方法对象
Method sAge = cl.getMethod("setAge", new Class[] { int.class });
//参数必须和方法中一样int和Integer,double和Double被视为不同的类型
Method gAge = cl.getMethod("getAge", null);
Method pName = cl.getMethod("printName", new Class[] { String.class });
Object[] args1 = { new Integer(25) };
// 参数列表
// emp为隐式参数该方法不是静态方法必须指定
sAge.invoke(emp, args1);
Integer AGE = (Integer) gAge.invoke(emp, null);
int age = AGE.intValue();
System.out.println("The Employee Age is: " age);
Object[] args3 = { new String("Jack") }; pName.invoke(emp, args3);
} catch (Exception e) { e.printStackTrace(); } System.exit(0); } }
class Employee {
// 定义一个员工类
public Employee() {
age = 0; name = null;
}
// 将要被调用的方法
public void setAge(int a) {
age = a;
}
// 将要被调用的方法
public int getAge() {
return age;
}
// 将要被调用的方法
public void printName(String n) {
name = n;
System.out.println("The Employee Name is: " name);
}
private int age;
private String name;
}