Java开发笔记(七十八)面向对象的后门——反射

做为一门面向对象的编程语言,Java认为一切皆是对象,每一个对象都能归属于某个类,甚至每一个类都可提取出一种特殊的类型,即Class类型。早在前面介绍多态的时候,就提到每一个类都存在独一无二的基因,经过比较实例的类基因与具体类名的类基因,便可分辨某个实例是否属于目标类。例如,若想获取公鸡类的类型,则可经过“类名.class”获得该类的Class对象,详细的获取代码以下所示:html

		// 第一种方式:经过“类名.class”获取
		Class clsFromClass = Cock.class;
		System.out.println("clsFromClass name = " + clsFromClass.getName());

 

相对应的,若想获取公鸡实例的类型,则可经过“实例名.getClass()”获得该实例的Class对象,详细的获取代码以下所示:java

		// 第二种方式:经过“实例名.getClass()”获取
		Cock cock = new Cock();
		Class clsFromInstance = cock.getClass();
		System.out.println("clsFromInstance name = " + clsFromInstance.getName());

 

既然Class也是一种数据类型,那么Class对象也能调用该类型的实例方法,好比上面两段例子代码都调用了Class的getName方法,该方法返回的是Class对象蕴含着的目标类类名,并且是包含完整包路径的类名。假如分别运行前面的两段示例代码,就会依次观察到以下的日志信息,从中可见getName方法确实返回了完整的类名:
clsFromClass name = com.addition.reflect.Cock
clsFromInstance name = com.addition.reflect.Cock
除了经过“类名.class”或者“实例名.getClass()”得到Class对象,甚至还能反向操做,只要提供一个保存完整类名的字符串,便可由该字符串生成目标类的Class对象,具体的获取代码格式形如“Class.forName("完整类名")”。经过类名字符串获取Class对象的代码示例以下,注意须要捕捉forName方法可能扔出的“类型未找到异常”ClassNotFoundException:编程

		// 第三种方式:经过该类的完整路径字符串获取
		try {
			Class clsFromString = Class.forName("com.addition.reflect.Cock");
			System.out.println("clsFromString name = " + clsFromString.getName());
		} catch (ClassNotFoundException e) { // 捕捉到类型未找到异常
			e.printStackTrace();
		}

 

上述这种经过字符串反向得到Class对象的操做被称为“反射”,仿佛光线照到镜子表面反射回来那样,看起来像是一种逆向操做。只是反射远非逆向操做这么简单,它还洞悉面向对象鲜为人知的各类奥秘,所以常常出现于一些高级的应用场合。
构成反射技术的基石主要有类型Class、字段Field、方法Method这三个好汉,其中尤以Class最为重要,它既是从其它类中提取出来的基因类型,又是一种能够直接访问的普通类型。之因此说Class普通,是由于它拥有若干能够被开发者访问的方法,使用体验与其它类型相比并无什么差别。下面是Class常见的方法说明:
equals:判断当前类型是否与目标类型相等。
getDeclaredFields:得到当前类型已声明的全部字段(字段即属性)。
getDeclaredField:根据指定的字段名称得到对应的字段(字段即属性)。
getDeclaredMethods:得到当前类型已声明的全部方法。
getDeclaredMethod:根据指定的方法名称以及参数类型列表得到对应的方法。
getName:获取当前类型包括包名在内的完整类名。
getPackage:获取当前类型所在的包名。
getSimpleName:获取当前类型的类名(不包括包名)。
getSuperclass:获取当前类型的父类类型。
以上的说明文字中,字段指的是Field类型,方法指的是Method类型,有关它们的详细用法将在后面的文章中加以阐述。编程语言



更多Java技术文章参见《Java开发笔记(序)章节目录日志

相关文章
相关标签/搜索