一、反射的作用

在Java中我们创建对象时一般都是类名+对象名。但反射给我们提供了另一种创建对象的方法,采用这种方法时,我们只需要知道类的名字就可以创建对象了。并且不需要知道类中的方法就可以直接使用。其作用就是在改写程序时较为方便,比如有一个类Class1,如果使用new Class1()来创建对象,那么当我们要换一个类Class2时就要重新改写代码进行编译;但如果使用反射class.forName(“Class1”).newInstance()来创建对象的话,要修改成Class2就只需要将class.forName(“Class1”).newInstance()中的Class1换成Class2即可。

二、获取一个类的构造方法

要获取一个类的构造方法首先要获取这个类,下面这句话可以实现Class c = Class.forName(“reflect.TestClass”)(TestClass是类名,reflect是包名)使用class类中的getDeclaredConstructor()方法可以获得在此类中声明的一个构造方法,根据传入的参数不同可以获得不同的构造方法(如果有多个的话),另一个方法getDeclaredConstructors()可以获得此类所有已声明的构造方法,代码如下

//若传入参数为int型可以写成这样
Constructor con1=c.getConstructor(int.class);
//获取所有构造方法
Constructor[] con1=c.getDeclaredConstructors();
创建对象可以用这个语句

//传入参数为11创建对象
Object obj1=con1.newInstance(11);

三、获取一个类的普通方法

在获取一个类后,使用getDeclaredMethod()方法可以获得在此类中声明的一个方法(无论公有还是私有),而使用getMethod()方法可以获取此类或从此类的父类中继承的公有方法

而使用getDeclaredMethods()和getMethods()方法可以获取上面对应的所有方法,代码如下

//输入方法名和要传入的参数获取方法
Method m1=c.getDeclaredMethod("fun1", int.class);
System.out.println(m1);
//getDeclaredMethods()获取自己在该类中声明的方法
Method[] m2=c.getDeclaredMethods();
//getMethods()获取该类全部公有方法(包括从父类继承的,私有方法无法获取)
Method[] m3=c.getMethods();
System.out.println(m1);
System.out.println(m2.length);
System.out.println(m3.length);

运行结果如下

public void reflect.TestClass.fun1(int)
4
11

四、获取一个类的属性

获取一个类的属性和获取方法差不多,有多种方法可以使用,参照第三点,下面看代码

//获取此类中的一个变量(无论公有私有)
Field f1=c.getDeclaredField("data1");
//获取此类中声明的所有变量(无论公有私有)
Field[] f2=c.getDeclaredFields();
//获取此类及其父类中所有公有变量
Field[] f3=c.getFields();
System.out.println(f1);
System.out.println(f2.length);
System.out.println(f3.length);

运行结果如下

public int reflect.TestClass.data1
4
2

五、关于私有属性赋值以及私有方法调用

私有方法一般不能在类外使用,但运用反射时又要使用,这时可以使用setAccessible()方法改变访问权限,代码如下

//m为已获取的方法
m1.setAccessible(true);
//obj1为该方法所属对象,11为传入该方法的参数
m1.invoke(obj1,11);

对属性赋值时也是一样

//f1为已获取的方法
f1.setAccessible(true);
f1.setInt(obj1, 1);
System.out.println(f1.getInt(obj1));

输出结果

11