【Java基础】RTTI与反射之Java

一、引言 

  很多时候我们的程序可能需要在运行时识别对象和类的信息,比如多态就是基于运行时环境进行动态判断实际引用的对象。在运行时识别对象和类的信息主要有两种方式:1.RTTI,具体是Class对象,它假定我们在编译时已经知道了所有类型。2.反射机制,运行我们在运行时发现和使用类的信息。

二、RTTI

  RTTI(Run-Time Type Infomation),运行时类型信息。可以在运行时识别一个对象的类型。类型信息在运行时通过Class对象表示,Class对象包含与类有关的信息,可以使用Class对象来创建类的实例。

  每个类对应一个Class对象,这个Class对象放在.class文件中,当我们的程序中首次主动使用某类型时,会把该类型所对应的Class对象加载进内存,在这篇文章JVM之类加载器中阐述了哪些情况符合首次主动使用。

  既然RTTI和Class对象有莫大的关系,即有了Class对象,就可以进行很多操作,那么,我们如何获取到Class对象呢?有三种方法1. Class.forName("全限定名");(其中,全限定名为包名+类名)。2. 类字面常量,如String.class,对应String类的Class对象。3.通过getClass()方法获取Class对象,如String str = "abc";str.getClass();。

  通过一个类对应的Class对象后,我们可以做什么?我们可以获取该类的父类、接口、创建该类的对象、该类的构造器、字段、方法等等。总之,威力相当大。

  下面我们通过一个例子来熟悉Class对象的各种用法。

 

  运行结果: 

 

  说明:使用method1、method2、method3三种方法都可以获得Class对象,运行结果是等效的。但是三者还是有稍许的区别。区别是从类的初始化角度来看的。如Class.forName("全限定名")会导致类型的加载、链接、初始化过程,而.class则不会初始化该类。显然,getClass肯定是会初始化该类的,因为这个方法时依托于类的对象。

  下面我们通过一个例子比较.class和forName()两种方法的区别。

 

  运行结果:

 

  说明:从结果也进一步验证了.class不会初始化类,而.forName()会初始化类。并且,对常量静态域的使用也不会导致类的初始化。

三、反射

  与RTTI必须在编译器就知道所有类型不同,反射不必在编译期就知道所有的类型,它可以在运行过程中使用动态加载的类,而这个类不必在编译期就已经知道。反射主要由java.lang.reflect类库的Field、Method、Constructor类支持。这些类的对象都是JVM在运行时进行创建,用来表示未知的类。

  关于两者的区别更深刻表达如下:对于RTTI而言,编译器在编译时打开和检查.class文件;对于反射而言,.class文件在编译时是不可获取的,所以在运行时打开和检查.class文件。

  其实在的第一个例子中我们已经用到了Constructor、Method类,现在我们来更加具体的了解Constructor、Method、Field类。  

 

  输入:boy

  运行结果: 

 

  说明:反射可以让我们创建一个类的实例、在类外部访问类的私有方法、私有字段。反射真的很强大~

四、动态代理-反射的应用

  动态创建代理并且动态处理对所代理方法的调用。在动态代理上所做的所有调用都会被重定向到单一的调用处理器上。

  下面是动态代理的例子

 

  运行结果: 

 

  说明:可以在invoke方法中进行过滤操作。过滤出以do开头的方法进行转发。

五、总结

  RTTI和反射分析就到此为止,RTTI和反射确实很强大,可以帮助我们干很多事情,用对地方绝对威力无穷,谢谢各位园友的观看~

  

时间: 2024-12-26 12:07:13

【Java基础】RTTI与反射之Java的相关文章

Java基础13:反射与注解详解

Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Oracle官方对反射的解释是 Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, and to use reflected fi

Java 基础篇之反射

Java 基础篇之反射 反射# 使用反射获取程序运行时的对象和类的真实信息. 获取 Class 对象# 每个类被加载之后,系统会为该类生成一个对应的 Class 对象,通过该 Class 对象可以访问到 JVM 中的这个类. 使用 Class 类的 forName(String clazzName) 静态方法.字符串参数的值是某个类的全限定类名,必须包含完整的包名 调用某个类的 class 属性 调用某个对象的 getClass() 方法.该方法是 java.lang.Object 类中的一个方

Java基础15:深入剖析Java枚举类

Java基础15:深入剖析Java枚举类 枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示. 初探枚举类 在程序设计中,有时会用到由若干个有限数据元素组成的集合,如一周内的星期一到星期日七个数据元素组成的集合,由三种颜色红.黄.绿组成的集合,一个工作班组内十个职工组成的集合等等,程序中某个变量取值仅限于集合中的元素.此时,可将这些数据集合定义为枚举类型. 因此,枚举类型是某类数据可能取值的集合,如一周内星期可能取值的

Java基础10:全面解读Java异常

Java基础10:全面解读Java异常 为什么要使用异常 首先我们可以明确一点就是异常的处理机制可以确保我们程序的健壮性,提高系统可用率.虽然我们不是特别喜欢看到它,但是我们不能不承认它的地位,作用. 在没有异常机制的时候我们是这样处理的:通过函数的返回值来判断是否发生了异常(这个返回值通常是已经约定好了的),调用该函数的程序负责检查并且分析返回值.虽然可以解决异常问题,但是这样做存在几个缺陷: 1. 容易混淆.如果约定返回值为-11111时表示出现异常,那么当程序最后的计算结果真的为-1111

Java基础1:深入理解Java面向对象三大特性

Java基础1:深入理解Java面向对象三大特性 三大特性:继承 封装 多态 继承 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类. 子类拥有父类非private的属性和方法. 子类可以拥有自己属性和方法,即子类可以对父类进行扩展. 子类可以用自己的方式实现父类的方法 Java中的继承只能单继承,但是可以通过内部类继承其他类来实现多继承. public class Son extends Father{publi

RTTI与反射之Java

一.引言 很多时候我们的程序可能需要在运行时识别对象和类的信息,比如多态就是基于运行时环境进行动态判断实际引用的对象.在运行时识别对象和类的信息主要有两种方式:1.RTTI,具体是Class对象,它假定我们在编译时已经知道了所有类型.2.反射机制,运行我们在运行时发现和使用类的信息. 二.RTTI RTTI(Run-Time Type Infomation),运行时类型信息.可以在运行时识别一个对象的类型.类型信息在运行时通过Class对象表示,Class对象包含与类有关的信息,可以使用Clas

java之RTTI和反射的理解

最近在读 Thinking in Java 这本书.读到类型信息这一张时,刚开始对书中所说的RTTI和反射彻底混了,不知道有什么联系,有哪些相同点和区别.于是在网上又找了些内容辅助理解,这一章又重新读了一遍,对上面的这些疑问有了自己的答案,想到RTTI和反射时,脑海中有了自己的轮廓. 它俩的目的一样: 在运行时,识别对象和类的信息. 相同点: 目的相同: 功能都是通过Class类来实现的 不同点: RTTI:(主要作用在多态中,比如参数传递) 它假定我们在编译时已经知道所有类型,会打开和检查所有

学习Spring必学的Java基础知识(1)----反射

引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓“登高必自卑,涉远必自迩”.以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Java基础知识,希望对大家有所帮助.): [1] Java反射知识-->Spring IoC :http://www.iteye.com/topic/1123081 [2] Java动态代理-->Spring AOP :http://www.iteye.com/topic/1123293 [3] 属性

java基础知识(十一)java反射机制(上)

java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时系统(JVM)对所有对象进行运行时类型标识,即Class对象,JVM可以通过该对象操作相应的类(如选准正确的方法执行). Class类用于封装被装入JVM中类(类或接口)的信息(类名.类型属于class.interface.enum还是annotation),是java反射机制的基础,通过Class