这篇博客对于Java中的反射机制,做一些总结,有不完善的地方再继续补充。
一. 定义
JAVA反射机制(The JAVA reflection mechanism)是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
二. 功能
在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
三. 使用
1.首先我们想通过反射获取类或者接口的属性和方法,就必须获得这个类或者接口的Class对象。有以下三种方法:
1).使用使用Class类的静态方法 Class.forName(String name)
2).类的语法,Stirng.class
3).使用类的实例化的getClass方法 obj.getClass();
2.获取类的构造器
1).public Constructor<?>[] getConstructors() 返回类中所有的public构造器集合,默认构造器的下标为0
2).public Constructor<T> getConstructor(Class<?>... parameterTypes) 返回指定public构造器,参数为构造器参数类型集合
3).public Constructor<?>[] getDeclaredConstructors() 返回类中所有的构造器,包括私有
4).public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回任意指定的构造器
3.获取类的成员变量
1).public Field getDeclaredField(String name) 获取任意指定名字的成员变量
2).public Field[] getDeclaredFields() 获取所有的成员变量
3).public Field getField(String name) 获取任意public成员变量
4).public Field[] getFields() 获取所有的public成员变量
Field 重要方法set(Object obj, Object value),将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
4.获取类的方法
1).public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 获取任意指定方法
2).public Method[] getDeclaredMethods() 获取所有的方法
3).public Method[] getMethods() 获取所有的共有方法的集合
4).public Method getMethod(String name,Class<?>... parameterTypes) 获取指定公有方法
Method重要方法invoke(Object obj ,Object…parmasType),调用由此 Method 对象表示的底层方法。
getMethods()和getDeclaredMethods()区别
getMethods()返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。
getDeclaredMethods()对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法。
示例代码:
1. StudentBean类
package com.li.reflection;
public class StudentBean {
public String id;
public String name;
public String sex;
public String age;
private String height;
public StudentBean() {
// TODO Auto-generated constructor stub
}
public StudentBean(String id) {
super();
this.id = id;
}
public StudentBean(String id, String name, String sex, String age) {
super();
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getHeight() {
return height;
}
public void setHeight(String height) {
this.height = height;
}
@Override
public String toString() {
return "StudentBean [id=" + id + ", name=" + name + ", sex=" + sex
+ ", age=" + age + ", height=" + height + "]";
}
private void goToSchool(){
System.out.println("Go to School");
}
public void eat(String food){
System.out.println("eat "+food);
}
public boolean finishHomework(){
System.out.println("finishHomework?");
return true;
}
}
2.使用
package com.li.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectionDemo {
public static void main(String[] args) throws Exception{
/**
* 想要通过反射来获取类或者接口的属性和方法,首先获得这个类或者接口的Class对象
*/
Class<?> cls;
System.out.println("------------------Get Class------------------");
//1.Class对象的静态方法 Class.forName(包名+类名)
cls = Class.forName("com.li.reflection.StudentBean");
//2.获得接口的静态方法 eg String.class
// cls = StudentBean.class;
//3.通过类或者接口的实例化对象 getClass()方法
// StudentBean student = new StudentBean();
// cls = student.getClass();
System.out.println(cls.toString());
//输出: class com.li.reflection.StudentBean
System.out.println("------------------Get Constructor------------------");
getConstructor(cls);
System.out.println("------------------Get Field------------------");
getField(cls);
System.out.println("------------------Get Method------------------");
getMethod(cls);
}
/**
* 获得构造器创建对象
*/
public static void getConstructor(Class<?> cls) throws Exception{
//获得构造器
Constructor<?>[] constructors = cls.getConstructors();
// Constructor<?>[] constructors = cls.getDeclaredConstructors();
for(Constructor cts : constructors){
System.out.println(cts.getName()+"-->"+cts.toString());
}
//输出:
// com.li.ref.StudentBean-->public com.li.ref.StudentBean()
// com.li.ref.StudentBean-->public com.li.ref.StudentBean(java.lang.String,java.lang.String,java.lang.String,java.lang.String)
// com.li.ref.StudentBean-->public com.li.ref.StudentBean(java.lang.String)
//获得默认无参构造方法
Constructor ct = cls.getDeclaredConstructor(null);
System.out.println(ct.toString());
//获得只有一个参数的构造方法
Constructor ct1 = cls.getDeclaredConstructor(new Class[]{String.class});
System.out.println(ct1.toString()); //public com.li.ref.StudentBean(java.lang.String)
//获得含有四个参数的构造方法
Constructor ct4 = cls.getDeclaredConstructor(new Class[]{String.class, String.class, String.class, String.class});
System.out.println(ct4.toString());
//需要含有默认无参的构造方法
StudentBean stu = (StudentBean) cls.newInstance();
System.out.println(stu.toString()); //StudentBean [id=null, name=null, sex=null, age=null, height=null]
//创建含一个参数的对象
StudentBean st = (StudentBean) ct1.newInstance("25");
System.out.println(st.toString()); //StudentBean [id=25, name=null, sex=null, age=null, height=null]
//创建含四个参数的对象
StudentBean st4 = (StudentBean) ct4.newInstance("1001","LiLei","male","16");
System.out.println(st4.toString()); //StudentBean [id=1001, name=LiLei, sex=male, age=16, height=null]
}
/**
* 获得类的属性
*/
public static void getField(Class<?> cls) throws Exception{
Field[] fields = cls.getDeclaredFields();
for(Field fd : fields){
fd.setAccessible(true);
System.out.println(fd.toString());
}
//输出:
// public java.lang.String com.li.ref.StudentBean.id
// public java.lang.String com.li.ref.StudentBean.name
// public java.lang.String com.li.ref.StudentBean.sex
// public java.lang.String com.li.ref.StudentBean.age
// private java.lang.String com.li.ref.StudentBean.height
Field field = cls.getDeclaredField("id");
System.out.println(field.toString()); //public java.lang.String com.li.ref.StudentBean.id
StudentBean stu = (StudentBean) cls.newInstance();
field.set(stu, "10010");
System.out.println(stu.toString()); //StudentBean [id=10010, name=null, sex=null, age=null, height=null]
}
/**
* 获取方法
*/
public static void getMethod(Class<?> cls) throws Exception{
Method[] methods = cls.getDeclaredMethods();
for(Method method : methods){
System.out.println(method.getName());
}
Method md = cls.getDeclaredMethod("goToSchool");
md.setAccessible(true);
StudentBean stu = (StudentBean) cls.newInstance();
md.invoke(stu);
Method method = cls.getDeclaredMethod("eat", String.class);
method.invoke(stu, "vegetable"); //输出:eat vegetable
}
}
坑爹的编辑器,看起来有点乱,聪明如你,肯定能看明白。