RTTI用于编译期查看程序信息,反射则是在运行期查看以及修改class信息,很多框架都会用到反射。
一、访问对于类对象
1、通过类的全路径名
Class clz = Class.forName("reflect.Person"); //类的全路径访问类对象
2、通过类名
Class clz=Person.class; //类名访问类对象
3、通过实例对象访问类对象
Person person=new Person();
Class clz=person.getClass(); //通过实例对象访问类对象
二、访问构造函数
1、Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公有(public)构造函数,params为参数类型,params可以为空,如果为空则配合newInstance()创建对象;
Constructor constructor = clz.getConstructor();
Object object = constructor.newInstance();
否则,配合newInstance(Object ... initargs)来构建有参对象(initargs为params类型的值)。
Constructor constructor2 = clz.getConstructor(String.class,int.class);
Object object2=constructor2.newInstance("lihua",3);
2、Constructor[] getConstructors() -- 获得类的所有公有(public)构造函数
3、Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的所有构造函数(包括public.private,protected等)
4、Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(包括public.private,protected等)
三、用于获得方法信息
1、Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法。name为方法名,params为方法的参数类型,params为空时可以通过两种方式表示
(1)Method method1=clz.getMethod("getAge");
method1.invoke(object)
(2)Method method2=clz.getMethod("getAge",new Class[]{});
method2.invoke(new Object[]{}))
params不为空时,则需要这样表示
Method method = clz.getMethod("setAge", int.class);
method.invoke(object, 4);
2、Method[] getMethods() -- 获得类的所有公共方法
3、Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法
4、Method[] getDeclaredMethods() -- 获得类声明的所有方法
四、对于字段信息
Field getField(String name) -- 获得命名的公共字段
Field[] getFields() -- 获得类的所有公共字段
Field getDeclaredField(String name) -- 获得类声明的命名的字段
Field[] getDeclaredFields() -- 获得类声明的所有字段
测试代码,Person.java
package reflect;
import java.io.Serializable;
public class Person implements Serializable {
public String name2;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name2 = name;
this.age = age;
}
public String getName2() {
return name2;
}
public void setName2(String name2) {
this.name2 = name2;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// get/set方法
}
Test.java:
package reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args){
try {
// Class clz=Person.class; //类名访问类对象
// Class clz = Class.forName("reflect.Person"); //类的全路径访问类对象
Person person=new Person();
Class clz=person.getClass(); //通过实例对象访问类对象
Method method = clz.getMethod("setAge", int.class);
Constructor constructor2 = clz.getConstructor(String.class,int.class);
Constructor constructor = clz.getConstructor();
Method method1=clz.getMethod("getAge");
Method method2=clz.getMethod("getName2",new Class[]{});
Object object2=constructor2.newInstance("lihua",3);
Object object = constructor.newInstance();
method.invoke(object, 4);
System.out.println(method1.invoke(object,new Object[]{}));
System.out.println(method2.invoke(object2));
clz.getDeclaredField("age").setAccessible(true);
System.out.println(clz.getDeclaredField("age"));
System.out.println(clz.getDeclaredField("name2"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
日志打印:
4
lihua
private int reflect.Person.age
public java.lang.String reflect.Person.name2
参考:1、Java基础之—反射(非常重要)