zoukankan      html  css  js  c++  java
  • Java开发笔记(七十八)面向对象的后门——反射

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

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

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

    		// 第二种方式:通过“实例名.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开发笔记(序)章节目录

  • 相关阅读:
    bzoj2957 -- 线段树
    bzoj2209 [ JSOI2011 ] -- splay
    bzoj3874 [ AHOI2014 ] -- 爬山算法
    bzoj1038 [ ZJOI2008 ] -- 模拟退火+二分
    bzoj2428 [ HAOI2006 ] -- 模拟退火
    bzoj3680 -- 模拟退火
    bzoj4500 -- 差分约束
    bzoj3527 -- FFT
    bzoj1013 [ JSOI2008 ] -- 高斯消元
    使用nginx try_files 指令 管理静态资源
  • 原文地址:https://www.cnblogs.com/pinlantu/p/10625285.html
Copyright © 2011-2022 走看看