反射(Reflection)总结

一、基础概念

1、反射(Reflection)就是将一个Java类中的每一个成分解析成一个Java类。

Java类用一个Class类的对象表示,其中一个类的基本组成成分:成员变量、方法、构造方法等信息用一个个的类来表示。而这个类的Class类选举要提供一系列的方法来获取其中的变量、方法等信息,这些信息使用 类的实例对象 来表示, 分别有Field、Constructor、Method、Package等。

其中一个class的成员都可以使用相应的API反射类的对象来表示。

2、得到一个类的Class对象的方法:(1)Person.class;(2)person1.getClass();(3)Class.forName("java.lang.String")。

 

测试展示部分:
1、Class类:

解释说明:(1)当一个类被载入时,jvm就自动为其生成一个class对象,我们便可以操作一个class对象。

(2)isPrimitive():表示是不是基本数据类型。

补充介绍Java8大基本类型:byte、short、int、long、float、double、boolean、char。

String str = "test";
		//三种获取class对象的方法
		Class c1 = Class.forName("java.lang.String");
		Class c2 = String.class;
		Class c3 = str.getClass();
		
		System.out.println(c1 == c2);// true
		System.out.println(c1 == c3);// true
		System.out.println(c1.isPrimitive()); // false
		System.out.println(int.class.isPrimitive()); // true

2、constructor类:

// 获取它所有的构造方法
		Constructor[] cs = Class.forName("java.lang.String").getConstructors();
		
		//获得一个指定的构造方法
		Constructor<String> constructor = String.class.getConstructor(StringBuffer.class);
		
		String str = constructor.newInstance(new StringBuffer("abc"));
		
		System.out.println(str.toString());// abc

3、Filed类:

一个Pointer类:

public class myPoint{

	public int px;
	private int py;// 私有
	
	public myPoint(int px, int py){
		super();
		this.px = px;
		this.py = py;
	}
	public myPoint(){
	}
}

通过反射操作获取其相关属性值:

	myPoint p1 = new myPoint(1, 2);

		// getFiled只能找到公有定义
		Field fx = myPoint.class.getField("px");
		System.out.println(fx.get(p1));// 1
		
		//无法访问
		Field fy = myPoint.class.getField("py");
		System.out.println(fy.get(p1));// 报错

以上结果显示无法访问私有属性值,接下来使用暴力反射:

		myPoint p1 = new myPoint(1, 2);

		// getFiled只能找到公有定义
		Field fx = myPoint.class.getField("px");
		System.out.println(fx.get(p1));// 1
		
		Field fy = myPoint.class.getDeclaredField("py");
		//暴力方法
		fy.setAccessible(true);
		System.out.println(fy.get(p1));// 2

4、Method类:

利用Method类做charAt(i),其中i是string的具体位置的字符,如hello,我们做str.charAt(1)操作:

String str = "hello";
				Method methodCharAt = String.class.getMethod("charAt", int.class);
				char target = (char)methodCharAt.invoke(str, 1);// 从0开始
				System.out.println(target);// e

 

二、利用Method、Filed、Constructor获取一个类的相关详细信息

利用Method获取一个类的成员函数的信息:

/**
	 * 获取类所有的信息:类的成员函数等
	 * @param obj
	 */
	public static void printMethodInformation(Object obj){
		//按照思路(或者说是步骤):先获得这个类(或者它的对应子类)的类类型
		Class c = obj.getClass();

		//输出这个类的类名
		System.out.println("这个类的名称:"+ c.getName());

		/*
		 * getMethods()方法:返回所有的public类型的方法,包括从父类继承过来的方法
		 * getDeclaredMethods: 获取所有的自身定义的方法,且不限制方法的类型(或者说是权限:public private protected)
		 * 获取它所有的方法 : 使用Method类
		 */
		Method[] ms = c.getMethods();

		// 遍历输出这个类方法的相关信息 》 ms获得的是一个类类型, 即可认为是.class
		for(Method mm : ms){
			//先得到方法返回值类型的类类型
			Class returnType = mm.getReturnType();
			System.out.print(returnType.getName() + " ");

			// 输出方法的名字以及参数的数据类型
			System.out.print(mm.getName() + "(");// 方法的名称

			//考虑此时可能有多个参数, 再写一个参数数组  :: 此时获取参数列表的类类型
			// parameter : 参数、系数、参量
			Class[] paraTypes = mm.getParameterTypes();
			for(Class o : paraTypes){
				//输出参数的数据类型
				System.out.print(o.getName() + ",");
			}
			System.out.println(")");
		}
	}

测试代码:String s = "nuist"; ClassUtil cu = new ClassUtil; cu.printMethodInformation(s);

输出方法的相关信息:这个类的类名、这个方法的返回值类型、这个方法的方法名以及各参数的数据类型:(参考截图:)

利用Field获取成员量的相关信息:

/**
	 * 成员变量也是对象
	 * 获取类所有的信息:类的成员变量, 利用的是一个类Filed, 其中Field类封装了关于成员变量的操作
	 * @param obj
	 */
	public static void printFiledInformation(Object obj){
		Class c = obj.getClass();
		//		System.out.println("这个成员变量的名称:"+ c.getName());

		/*
		 * getFields()方法:返回所有的public类型的成员变量
		 * getDeclaredFields(): 获取所有的自身定义的成员变量的信息
		 */
		//			Field[] f = c.getFields();// java.util.Comparator CASE_INSENSITIVE_ORDER

		Field[] f = c.getDeclaredFields();
		for(Field field : f){
			//先得到成员变量类型的类类型
			Class fieldType = field.getType();
			//成员变量类型的名字
			String typeName = fieldType.getName(); 
			//输出这个成员变量的名字
			String fieldName = field.getName();

			System.out.println(typeName + " " + fieldName);
		}
	}

测试代码:Integer in1 = 20; cu.printFiledInformation(in1); 

输出成员变量的相关信息:成员变量类型的名称,以及成员变量的变量名:(参考截图:)

利用Constructor获得构造函数的所有内容:

/**
	 * 获取构造函数的所有的信息:利用的是一个类Constructor, 其中Constructor类封装了关于构造函数的操作
	 * @param obj
	 */
	public static void printConstuctorInformation(Object obj){
		Class c = obj.getClass();
		/*
		 * getConstructors()方法:返回所有的public类型的构造函数
		 * getDeclaredConstructors(): 获取所有的自己定义的构造函数的信息
         */
		Constructor[] cons = c.getDeclaredConstructors();
		for(Constructor con : cons){
			//获取构造函数的名称
			System.out.print(con.getName() + "(");
			//获取构造函数参数变量列表的类类型
			Class[] paraTypes = con.getParameterTypes();
			for(Class cla : paraTypes){
				//输出参数的数据类型
				System.out.print(cla.getName() + ",");
			}
			System.out.println(")");
		}
	}

测试代码:ClassUtil.printConstuctorInformation("good");
                ClassUtil.printConstuctorInformation(new Integer(2));

参考截图:

 

以上便是这篇的全部内容,欢迎您提出改进意见,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值