版权声明:转载或者引用本文内容请注明来源及原作者 https://blog.csdn.net/a755199443/article/details/88410404
反射机制是java中非常强大的一个功能,之前我介绍了如何获得Class/Field/Method/Constructor对象,今天就来讲一讲获得的这些对象应该如何使用.
创建对象实例
我们可以通过两种反射机制的方法来创建对应类的实例
- Class对象调用newInstance()通过无参构造器创建对象实例,返回的是Object类型对象(相当于User对象向上自动转型了)
- Constructor对象调用newInstance(Object… initargs) 通过指定参数构造器创建对象实例,返回的也是Object类型对象
首先新建一个实验用的User类对象
public class User {
private int userId; //注意 这个成员变量都是私有的 在之后会用到暴力访问
public String name;
private void show() { //注意 show()为私有方法 在之后会用到暴力访问
System.out.println("私有方法");
}
public User(int userId, String name) {
this.userId = userId;
this.name = name;
}
public User() {
}
public int getUserId() {
return userId;
}
public void setuserId(int userId) {
this.userId = userId;
}
public String getName() {
return name;
}
@Override
public String toString() { //重写了toString方法 以便打印对象属性
return "User [userId=" + userId+ ", name=" + name + "]";
}
public void setName(String name) {
this.name = name;
}
}
现在用第一种Class对象的方法创建User对象
public class TestUser {
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
//首先获得User的Class对象
Class userClass=User.class;
User user1=(User) userClass.newInstance(); //请注意Class类的newInstance返回的是Object类型对象,需要向下强制转换
System.out.println(user1);
}
}
运行结果为:
接着用第二种Constructor对象的方法创建User对象:
public class TestUser {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
//首先获得User的Class对象
Class userClass=User.class;
//获得Constructor对象
Constructor con1=userClass.getConstructor(); //con1指向无参数构造器对象
Constructor con2=userClass.getConstructor(int.class,String.class); //con2指向两个参数的构造器对象
//开始创建对象
User u1=(User)con1.newInstance(); //需要向下强制转型
User u2=(User)con2.newInstance(20,"朱同学"); //需要向下强制转型
System.out.println("u1:"+u1+"\nu2:"+u2);
}
}
运行结果为:
执行方法
首先要获得Method对象,对其调用invoke(Object obj,Object… args)方法执行你获得的Method对象对应的方法,第一个参数为调用方法的对象,之后的参数为提供给方法的实参,执行私有方法前,必须设置可以访问为真,不然抛出IllegalAccessException异常.
public class TestUser {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
//首先获得User的Class对象,并创造User
Class userClass=User.class;
User user=(User) userClass.newInstance();
//获得Method对象
Method m1=userClass.getMethod("setUserId",int.class);
Method m2=userClass.getDeclaredMethod("show",null);
m2.setAccessible(true); //执行私有方法前,必须设置可以访问为真,不然抛出IllegalAccessException异常
//使用invoke()开始调用方法
m1.invoke(user, 40); //第一个参数为调用方法的对象,之后的参数为提供给方法的实参
m2.invoke(user); //对于无参方法可以省略后面的部分
System.out.println(user);
}
}
运行结果为:
更改属性
首先获得Field对象,对其调用set(Object obj, Object value) 方法设置新的值,第一个参数为设置属性的对象,第二个参数为设置的值,设置私有属性前,必须设置可以访问为真,不然抛出IllegalAccessException异常.
public class TestUser {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
//首先获得User的Class对象,并创造User
Class userClass=User.class;
User user=(User) userClass.newInstance();
//获得Field对象
Field f1=userClass.getDeclaredField("userId");
Field f2=userClass.getDeclaredField("name");
f1.setAccessible(true); //设置私有属性前,必须设置可以访问为真,不然抛出IllegalAccessException异常
//开始设置属性
f1.set(user, 40); //第一个参数为设置属性的对象,第二个参数为设置的值
f2.set(user,"朱同学"); //类型不匹配会抛出IllegalArgumentException异常
System.out.println(user);
}
}
运行结果为:
今天就到这里结束啦,您能点个赞的话我就很高兴啦.