[java]反射机制基础知识之创建对象实例/执行方法/更改属性

版权声明:转载或者引用本文内容请注明来源及原作者 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);
	}
}

运行结果为:
在这里插入图片描述

今天就到这里结束啦,您能点个赞的话我就很高兴啦.

猜你喜欢

转载自blog.csdn.net/a755199443/article/details/88410404
今日推荐