所谓反射,是指在运行时状态中,获取类中的属性和方法,以及调用其中的方法的一种机制。这种机制的作用在于获取运行时才知道的类(Class)及其中的属性(Field)、方法(Method)以及调用其中的方法,也可以设置其中的属性值。
在Java中实现反射最重要的一步,也是第一步就是获取Class对象,得到Class对象后可以通过该对象调用相应的方法来获取该类中的属性、方法以及调用该类中的方法。
下面看看代码的实现过程:
首先定义一个Stu类,这个类当中有公有的字段和公有的方法,也有私有的字段和私有的方法
class Stu{
public String name;
private int age;
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Stu(){}
public Stu(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Stu [name=" + name + ", age=" + age + "]";
}
public void fun1(){
System.out.println("这是一个无参的公有的方法");
}
public void fun2(int age){
System.out.println("这是一个有参数的公有方法"+age);
}
public String fun3(String name){
System.out.println("这是一个有参并且有返回值的方法:");
return name;
}
private void fun4(){
System.out.println("这是一个私有的方法");
}
}
再来运用反射来获取这个类当中的字段和方法,以及其他东西:
package xusheng.shagnhai.mianshi;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflctDemo {
public static void main(String[] args) {
try {
Stu stu = new Stu();
Class<?> c =Class.forName("xusheng.shagnhai.mianshi.Stu");
Object object = c.newInstance();
Method[] method = c.getMethods(); //这样返回的是公有的方法
for (Method method2 : method) {
System.out.println(method2.getName());
}
Method[] method3 = c.getDeclaredMethods();//这样返回的是所有的方法,包括私有的方法
for (Method method2 : method3) {
System.out.println(method2.getName());
}
//这样返回的是所有的属性
Field[] field = c.getFields();
for (Field field2 : field) {
System.out.println(field2.getName());
}
//这样返回的是属性并且包括有私有的属性
Field[] fields = c.getDeclaredFields();
for (Field field2 : fields) {
System.out.println(field2.getName());
}
//调用无参的方法
Method method2 = c.getMethod("fun1");
method2.invoke(object);
//调用一个有参数的方法
Method method4 = c.getMethod("fun2", int.class);
method4.invoke(object, 22);
//调用一个有参数并且有返回值的方法
Method method5 = c.getMethod("fun3", String.class);
String string = method5.invoke(object, "zhangxusheng")+"";
System.out.println(string);
//通过反射来获取一个私有方法的时候
Method method6 = c.getDeclaredMethod("fun4");
//不加这一行代码会报错:can not access a member of class Stu with modifiers "private"
method6.setAccessible(true);
method6.invoke(object);
//通过反射来获得一个类当中所有的字段
Field[] fields2 = c.getFields();
for (Field field2 : fields2) {
System.out.println(field2.getName()); //只能是公有的
}
Field[] fields3 = c.getDeclaredFields();
for (Field field2 : fields3) {
System.out.println(field2.getName());
System.out.println(field2.toGenericString()); //这样返回的是这个字段的修饰类型
}
//通过反射来给字段赋值
Field field2 = c.getDeclaredField("age"); //首先获得这个字段对象
field2.setAccessible(true);
//通过字段对象来执行方法给字段赋值
field2.set(stu, 22);
System.out.println(field2.get(stu));
//通过反射获得它的构造方法
Constructor[] constructor = c.getConstructors();
for (Constructor constructor2 : constructor) {
System.out.println(constructor2.toGenericString());
}
//通过反射来获取此类的父亲
Class class1 = c.getSuperclass();
System.out.println(class1.getName());
//获得此类的接口
Class[] class2 = c.getInterfaces();
for (Class class3 : class2) {
System.out.println(class3.getName());
}
//通过反射来获取此类的包
Package package1 = c.getPackage();
System.out.println(package1);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}