java 类反射3


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.junit.Test;

public class ReflectOperateObj {
	/*
	 * 理一下 传统方式: User u=new User();
	 * 
	 * 类反射的方式 Class c=Class.forName("cn.hncu...User");//1 Class paramTypes[]=
	 * {String.class,int.class}; Constructor con = c.getConstructor(paramTypes);
	 * //2 Object params[] = {"Jack",25}; Object u=con.newInstance(params); //3
	 * 
	 * 
	 * Class c = Class.forName("cn.hncu...User"); //1Constructor con =
	 * c.getConstructor( new Class[]{String.class,int.class} ); //2Object u =
	 * con.newInstance( new Object[]{"Jack",25} ); //3
	 */

	// 构造器的操作(调用)
	@Test
	public void operateConstructor() throws Exception {
		Class<?> c = Class.forName("cn.hncu.reflect.fetch.User");

		// 1 该方式只能调用空参构造器
		Object obj = c.newInstance();
		System.out.println(obj);

		// 2 调用指定的构造器如: public User(String name, int age)
		// ///2.1先获取指定的构造器///

		/*
		 * //形参是可变参数,传实参时可以是若干个实参 Class c1=String.class; Class c2=int.class;
		 * Constructor con = c.getDeclaredConstructor(c1,c2);
		 * System.out.println(con);
		 */
		// 形参是可变参数,传实参时也可以是一个实参数组
		/*
		 * Class paramTypes[] = new Class[2]; paramTypes[0] = String.class;
		 * paramTypes[1] = int.class; Constructor con =
		 * c.getDeclaredConstructor(paramTypes); //关键点1
		 */
		Constructor<?> con = c.getDeclaredConstructor(new Class[] {
				String.class, int.class });
		// System.out.println(con);

		// //2.2 调用指定的构造器对象con/// new User("Jack",22);
		Object params[] = new Object[2];
		params[0] = "Jack";
		params[1] = 22;
		Object obj2 = con.newInstance(params);
		System.out.println(obj2);
	}

	// 方法的操作(调用)
	@Test
	public void operateMethod() throws Exception {
		// 1加载类模板(获得class对象)
		Class<?> c = Class.forName("cn.hncu.reflect.fetch.User");

		// 调用方法
		// ※2.1调用"空参"方法,如toString() ---User u = new User(); u.toString()
		// 1)先获取指定方法
		Method m1 = c.getDeclaredMethod("toString", null);
		// 2)再调用
		// Object u = c.newInstance();
		Object u = new User("张三", 20);
		Object returnValue = m1.invoke(u, null); // u.toString();
		System.out.println(returnValue);

		// ※2.2调用"有参"方法, 如:public double sum(int a, double b) ----returnValue =
		// u.sum(100,55.6)
		// 1)先获取指定方法
		Class<?> parameterTypes[] = new Class[2];
		// parameterTypes[0] = int.class;//AC
		// parameterTypes[0] = Integer.class;//WA ---类反射中的方法参数匹配没有装箱拆箱
		parameterTypes[0] = Integer.TYPE;// AC ---包装类的TYPE属性就是对应的基本数据类型
		parameterTypes[1] = double.class;
		// parameterTypes[1] = Double.class;//WA
		// parameterTypes[1] = Double.TYPE;//AC
		Method m2 = c.getDeclaredMethod("sum", parameterTypes);// 关键点1
		// 2)再调用
		Object u2 = c.newInstance();
		Object args[] = { 100, 55.6 };
		Object returnValue2 = m2.invoke(u2, args); // 关键点2 returnValue =
													// u2.sum(100,55.6)
		System.out.println("returnValue2: " + returnValue2);

		// ※2.3调用静态方法, 如:final static void aa()
		// 1)先获取指定方法 (私有方法必须通过Declared方式获取)
		Method m3 = c.getDeclaredMethod("aa", null);
		// 2)再调用
		Object returnValue3 = m3.invoke(null, null);
		System.out.println("returnValue3: " + returnValue3);
	}

	// 演练一下,用类反射构造并封装一个User对象
	@Test
	public void operateConstructorMethod() throws Exception {
		// 加载类模板
		Class<?> c = Class.forName("cn.hncu.reflect.fetch.Person");
		// 调用构造器
		Class<?> parameterTypes[] = { String.class, int.class };
		Constructor<?> con = c.getConstructor(parameterTypes);
		Object obj = con.newInstance("王五", 30); // obj = new User("王五",30)
		Method m = c.getMethod("setId", String.class);
		m.invoke(obj, "U001"); // obj.setId("U001");
		System.out.println(obj);
	}

	// 属性的操作(调用)
	@Test
	public void operateField() throws Exception {
		// 1加载类模板(获得class对象)
		Class<?> c = Class.forName("cn.hncu.reflect.fetch.User");

		// 2获取指定的属性
		Field fld = c.getField("a");

		// 3操作该属性 //读取属性值 User u = new User(); u.a
		Object u = c.newInstance();
		// fld.set(u, 200); //设置属性值
		// fld.setDouble(u, 123);//WA:方法与fld属性 类型不匹配
		fld.setInt(u, 12);

		// 读取属性值
		Object value = fld.get(u); // 方式1: 通用,但获取的属性值类型比较模糊(Object)
		int value2 = fld.getInt(u); // 方式2:专用,获取的属性值类型精确,类似函数还有:getBoolean(obj),getChar(obj),需要和fld对应的类型匹配
		System.out.println(value + "," + value2);
	}
	
	//暴力访问----该问非公开权限的构造器、方法或属性
		@Test
		public void accessViolence() throws Exception{
			Class<?> c = Class.forName("cn.hncu.reflect.fetch.User");
			Field fld = c.getDeclaredField("id");
			Object obj = new User(); //Object obj = c.newInstance();
			
		    fld.setAccessible(true); //打开暴力访问开关,注:该方法是AccessibleObject类中的方法,该类是Field、Method和Constructor的公共父类,因此都可以调用以进行暴力访问。
			fld.set(obj, "U007");
			System.out.println(obj);
		
		}
		
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值