美文网首页
执行期型别识别

执行期型别识别

作者: 刚子来简书啦 | 来源:发表于2020-09-25 09:28 被阅读0次

Java提供“执行期间让你得以找出对象及class相关信息”。包括两种形式:第一种是“传统的”RTTI(Run-Time Type Identification)机制,它假设你在编译期和执行期拥有所有型别信息。第二种是reflection机制,允许你在执行期间找出和class相关的信息。

Class对象

执行期间采用的是隶属Class的特别的对象来表示型别信息。Class对象内包含与class相关的各种信息。程序中的每个class都有一个相应的Class对象。换句话说,每写一个新的class并编译完成,就会产生一个Class对象存储与相同的.class文件内。执行期间当你想要产生该class的对象时,Java虚拟机(JVM)便会先检查该型别的Class对象是否已被装载。如果尚未装载,JVM会根据名称找到.class文件并装载它。因此Java程序启动时并不会将整个程序都转载。一旦某个型别的Class对象已被装载内存,它就可以被用来产生该型别的所有对象。

Class.forName("Student");

这是Class(所有Class对象皆属此一类型)的一个static成员。Class对象就像其它对象一样,可以取其reference并加以操作(这也是装载器所做的工作)。取得Class object reference的方法之一便是调用forName(),它接受一个字符串作为引数,字符串内含某个“你想取其Class对象”的reference的文本表达式。它会返回一个Class reference。

Student.class;

Java通过所谓的“类字面量”提供第二种方式来取得“指向Class对象”的reference。这么做不仅简单,也更安全,因此检查动作在编译期就进行了。由于它不用调用任何函数,所以也更有效率。

所有基本型别的外覆类都有一个名为TYPE的标准数据,能够产生一个reference,指向相应的基本型别的Class对象。例如 boolean.class 可以使用 Boolean.Type 来获取。

Reflectoin(反射)

Java提供一个java.lang.reflect程序库,其中含有Field、Method、Constructor等class。这些型别的对象是由JVM于执行期产生,用来代表未知class内的相应成员。可以使用Constructor来产生新对象,使用get()和set()来读取或设定相应于Field对象的数据值,也可以使用invoke()来调用相应于Method对象的函数。也可以调用getFields()、getMethods()、getConstructors()等,它们会传回数组,内含“代表数据成员、函数、构造函数”的对象。因此,即使完全不认识某个对象,编译器无法获得其任何信息,仍然可以在执行期找出其完整的class信息。

当使用reflection来处理型别未知的对象,JVM会先检视该对象,检查它是否属于某个class。不过,稍后在JVM开始对它进行一些动作之前,得先将Class对象装载,因此JVM必须能够取得该型别所对应的.class文件,不论是在本机还是跨网络获取。RTTI的差别在于,编译器在编译期即开启检查.class文件,但如果采用reflection机制,编译期并不会取用.class文件,它会由执行期环境加以开启和检验。

try {
    Class c = Class.forName("com.cage.home.io.ArrayUtil");
    Constructor con = c.getConstructor();
    Object co = con.newInstance();
    Method methodCheck = c.getMethod("check");
    methodCheck.invoke(co);
} catch (Exception e) {
    System.out.println("Exception--");
    System.out.println(e.getClass());
    System.out.println(e.getMessage());
}

forName()中的字符串必须是全路径的类名称。当invoke一个static方法时,对象参数传null即可。另外,通过Class直接进行newInstance()的方法已被deprecated,需要使用constructor来创建Class的对象。

相关文章

  • 执行期型别识别

    Java提供“执行期间让你得以找出对象及class相关信息”。包括两种形式:第一种是“传统的”RTTI(Run-T...

  • flow中文文档(六)

    类型别名 类型别名语法 类型别名泛型 不透明类型别名 子类型约束 类型别名 当您有要在多个位置重用的复杂类型时,可...

  • 齿轮说干货:人脸识别那些事

    人脸识别,一种基于人的脸部特征信息进行身份认证的生物特征识别技术。 五一出行期间,各景点、车站“刷脸”准入的出现率...

  • Flow不透明类型别名(Opaque Type Aliases)

    不透明类型别名(Opaque Type Aliases) 通过类型系统加强抽象 不透明类型别名是类型别名,它们不允...

  • TypeScript基础入门之高级类型的类型别名

    转发 TypeScript基础入门之高级类型的类型别名 高级类型 类型别名 类型别名会给一个类型起个新名字。 类型...

  • 行期

    风高秋霜月影白 寒风古都人未回 冬时雪冬远行去 至此已是月阑珊

  • 迭代器

    迭代器榨汁机 迭代器型别 迭代器型别之一:value_typevalue_type 是指对象的型别,每一个打算与S...

  • TypeScript(八):类型别名和类型断言

    类型别名,使用 type 关键字 上面 sum2 函数类型定义很麻烦,可以使用类型别名: 类型别名,最常用的是使用...

  • Swift基础(四)类型别名 元组 可选类型

    类型别名 类型别名对当前的类型定义了另一个名字,类型别名通过使用 typealias 关键字来定义。 元组 元组(...

  • 01_GO语言中级学习之类型(type)

    类型别名与类型定义 类型别名 以下代码使用的就是类型别名,例码: 类型定义 以下代码使用的就是类型定义,例码: 两...

网友评论

      本文标题:执行期型别识别

      本文链接:https://www.haomeiwen.com/subject/lksnphtx.html