上一篇文章中了解了Java的反射机制和获取类信息的一些基本方法,不过仅仅是获取了类的相关信息则不能价格Java反射机制的意义给体现出来,为此,我们还需要对其来进行使用。
1. 创建对象
我们先来创建一个测试类,如下:
public class Super {
private int supPri = 1;
int supPac = 2;
protected double supPro = 3;
public String supPub = "4";
public Super(){}
public Super(int supPri, int supPac, double supPro, String supPub) {
this.supPri = supPri;
this.supPac = supPac;
this.supPro = supPro;
this.supPub = supPub;
}
protected Super(int supPri, int supPac, double supPro){
this(supPri,supPac,supPro,"4");
}
Super(int supPri, int supPac) throws Exception{
this(supPri,supPac,3.0,"4");
}
private Super(int supPri){this(supPri,2,3.0,"4");}
private void supPrivate(){}
int supPackage(){return supPac;}
protected double supProtected(){return supPro;}
public String supPublic(){return supPub;}
}
(1)使用newInstance()方法创建对象
public class TestNewInstance {
public static void main(String[] args) throws
ClassNotFoundException,
IllegalAccessException,
InstantiationException {
//获取Class对象
Class c = Class.forName("com.zane.spbootdemo.reflecttest.Super");
//通过class的newInstance()方法创建对象
Super sup = (Super)c.newInstance();
System.out.println(sup.supPac);
}
}
输出结果为 : 2
上述中使用的newInstance()方法其 实际是与Super sup = new Super()等价。
(2)使用有参构造方法进行创建对象
该方法是使用Constructor中的newInstance(Object[] args)方法来创建对象的。
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class TestConstructor {
public static void main(String[] args) throws
ClassNotFoundException,
NoSuchMethodException,
IllegalAccessException,
InvocationTargetException,
InstantiationException {
//获取Class对象
Class c = Class.forName("com.zane.spbootdemo.reflecttest.Super");
//通过构造方法来创建对象
Constructor constructor = c.getDeclaredConstructor(new Class[]{int.class, int.class});
Super sup = (Super) constructor.newInstance(new Object[]{21, 22});
System.out.println(sup.supPackage());
}
}
2. 修改属性
和上面类似,其对应的api在Field中。
public class TestField {
public static void main(String[] args) throws
ClassNotFoundException,
IllegalAccessException,
InstantiationException,
NoSuchFieldException {
//获取属性测试类
//1.获取Class对象
Class c = Class.forName("com.zane.spbootdemo.reflecttest.Super");
//2.创建对象
Super sup = (Super)c.newInstance();
//通过属性名获取属性对象,这里的supPri为私有属性名
Field supPri = c.getDeclaredField("supPri");
//取消私有属性的访问权限
supPri.setAccessible(true);
//调用get(Object o)方法来获取对象o对应的属性值
System.out.println("取消访问控制权限后访问supPri,值为:"+supPri.get(sup));
//调用set(Object o,Object v)方法设置修改对象o的对应属性值
supPri.set(sup,20);
System.out.println("supPri修改后的值为:"+supPri.get(sup));
}
}
结果:
取消访问控制权限后访问supPri,值为:1
supPri修改后的值为:20
在上述例子中,由于Super中的非private属性在创建对象后即可通过sup.xxx来获取,所以用非private修饰的属性来做例子没有意义,于是用private属性的supPri来做例子会比较合适。
通过Field类,我们可以修改属性的访问控制权限和属性值。
3. 调用方法
调用方法涉及到的类是Method类。
//反射机制获取方法的测试类。
public class TestMethod {
public int add(int x, int y){
return x+y;
}
public static void main(String[] args) throws
IllegalAccessException,
InstantiationException,
NoSuchMethodException,
InvocationTargetException {
Class c = TestMethod.class;
Object obj = c.newInstance();
//通过方法名和方法参数来获取方法对象
Method add = c.getDeclaredMethod("add", new Class[]{int.class, int.class});
//通过invoke(Object o,Object[] args)来调用对象o的方法
System.out.println("调用方法:add,输入值为3和4,结果为:"+
add.invoke(obj,new Object[]{3,4}));
}
}
结果:
调用方法:add,输入值为3和4,结果为:7
总结:这次价格Java反射机制重新复习了一边,解决了之前只有一个模糊的思想,由于之前老师讲的时候一笔带过,而且自己又不怎么理解,通过这次狠了心地学习,终于将常用地用法都掌握了。不过还是得多练多写代码才可以。