作为一门面向对象的编程语言,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开发笔记(序)章节目录

Java开发笔记(七十八)面向对象的后门——反射的更多相关文章

  1. Java开发笔记(十八)上下求索的while循环

    循环是流程控制的又一重要结构,“白天-黑夜-白天-黑夜”属于时间上的循环,古人“年复一年.日复一日”的“日出而作.日落而息”便是每天周而复始的生活.计算机程序处理循环结构时,给定一段每次都要执行的代码 ...

  2. Java开发笔记(九十八)利用Callable启动线程

    前面介绍了如何利用Runnable接口构建线程任务,该方式确实方便了线程代码的复用与共享,然而Runnable不像公共方法那样有返回值,也就无法将线程代码的处理结果传给外部,造成外部既不知晓该线程是否 ...

  3. Java开发学习(二十八)----拦截器(Interceptor)详细解析

    一.拦截器概念 讲解拦截器的概念之前,我们先看一张图: (1)浏览器发送一个请求会先到Tomcat的web服务器 (2)Tomcat服务器接收到请求以后,会去判断请求的是静态资源还是动态资源 (3)如 ...

  4. Java学习笔记二十八:Java中的接口

    Java中的接口 一:Java的接口: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来继承 ...

  5. Java学习笔记(十八)——Java DTO

    [前面的话] 在和技术人员的交流中,各种专业术语会出现,每次都是默默的记录下出现的术语,然后再去网上查看是什么意思.最近做项目,需要使用到DTO,然后学习一下吧. 这篇文章是关于Java DTO的,选 ...

  6. 【Java学习笔记之十八】Javadoc注释的用法

    Javadoc注释的用法 Java 文档 // 注释一行/* ...... */ 注释若干行/** ...... */ 注释若干行,并写入 javadoc 文档 通常这种注释的多行写法如下: /*** ...

  7. Java开发笔记(十九)规律变化的for循环

    前面介绍while循环时,有个名叫year的整型变量频繁出现,并且它是控制循环进出的关键要素.不管哪一种while写法,都存在三处与year有关的操作,分别是“year = 0”.“year<l ...

  8. 安卓开发笔记(十八):实现button按钮事件的三种方法

    Android开发中有三种主要的方式用于设置View的点击事件,1.创建内部类:2.主类中实现OnClickListener接口:3.使用匿名内部类.这三种方式都用到了OnClickListener接 ...

  9. Java开发笔记(十)一元运算符的技巧

    前面讲到赋值运算符的时候,提到“x = x+7”可以被“x += 7”所取代,当然Java编程中给某个变量自加7并不常见,常见的是给某变量自加1,就像走台阶,一般都是一级一级台阶地走,犯不着一下子跳上 ...

  10. Java开发笔记(十二)布尔变量论道与或非

    在编程语言的设计之初,它们除了可以进行数学计算,还常常用于逻辑推理和条件判断.为了实现逻辑判断的功能,Java引入了一种布尔类型boolean,用来表示“真”和“假”.该类型的变量只允许两个取值,即t ...

随机推荐

  1. Jvm 内存模型 —— GC

    一.Jvm 原理 二.Jvm 运行时数据区( Run-Time Data Areas ) (主要是关于 non-stack 区域的详细划分) 从上图可以清楚地看到:程序计数器.Jvm 栈.本地方法栈 ...

  2. 无需sendmail:巧用LD_PRELOAD突破disable_functions

    *本文原创作者:yangyangwithgnu,本文属FreeBuf原创奖励计划,未经许可禁止转载 摘要:千辛万苦拿到的 webshell 居然无法执行系统命令,怀疑服务端 disable_funct ...

  3. webpack配置非CMD规范的模块

    一.前言 webpack在配置多页面开发的时候 ,发现用 import 导入 Zepto 时,会报 Uncaught TypeError: Cannot read property 'createEl ...

  4. GameFreamWork框架----事件系统的应用

    事件系统用途广泛,对处理玩家数据有很大帮助(玩家金币,经验,等级),让数据多次调用,降低耦合 在unity中应用(以玩家金币发生变化来演示); 1).注册监听 2).移出监听 3).金币发生变化的时候 ...

  5. Tensorboard可视化(关于TensorFlow不同版本引起的错误)

    # -*- coding: utf-8 -*-"""Created on Sun Nov 5 15:28:50 2017 @author: Administrator&q ...

  6. Dubbo架构设计及原理详解

    Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服务模型的角度来看,Dubbo采用的是一种非常简单的模 ...

  7. 【DFS】素数环问题

    题目: 输入正整数n,对1-n进行排列,使得相邻两个数之和均为素数,输出时从整数1开始,逆时针排列.同一个环应恰好输出一次.n<=16 如输入: 6 输出: 1 4 3 2 5 6 1 6 5 ...

  8. 【逆元】HDU-1576

    逆元: 同余方程 ax≡1(mod n),gcd(a,n) = 1 时有解,这时称求出的 x 为 a 的对模n的乘法逆元.(注意:如果gcd(a,n)如果不等于1则无解),解法还是利用扩展欧几里得算法 ...

  9. PHP实现用户注册并保存数据到文件

    首先我们实现功能时,分析实现的步骤是什么,就这个而言,我们应该接收用户提交的数据并进行校验,然后保存在文件,最后给用户反馈. 这里需要注意的是为了避免嵌套过深,这里使用自定义函数来实现,其代码如下: ...

  10. Kubernetes---Pod控制器

    Pod作为kubernetes的最基本单元,它的控制器有以下这些 Pod的控制器: 1,  RC ( ReplicationController): 2, RS(ReplicaSet) : 3, De ...