JAVA 笔记(四) RTTI - 运行时类型检查

运行时类型信息(RTTI) 在C++中,RTTI可以通过运算符进行安全的类型转换,并可以通过typeid运算符和类在运行时操作类型信息。在Object Pascal中,RTTI可以通过as运算符进行安全的类型转换,使用is等类)。在Ada中,带标签的类型对象也存储类型标签,这允许在运行时识别这些对象的类型。in运算符可以在运行时测试对象是否属于特定类型并安全地转换。RTTI仅适用于多态类,即包含至少一个虚方法的类。在实践中,这并不构成限制,因为基类必须具有虚析构函数,以便从基类指针删除派生类对象时可以执行正确的清理操作。 阅读详情

运行时类型检查,即Run-time Type Identification。这是Java语言里一个很强大的机制,那么它到底给我们的程序带来了什么样的好处呢?
在了解运行时类型检查之前,我们要首先知道另一个密切相关的概念,即运行时类型信息(Run-time Information - 也可以缩写为RTTI)
运行时类型信息使得你可以在程序运行时发现和使用类型信息。 来自:《Thinking in Java》。
OK,那么我们总结来说,RTTI就是能够让我们在程序的运行时去获取类型的信息。接下来我们就逐级的去了解RTTI常见的使用方式。

  • A = (A)b; 向下转型

面向对象编程的一个重要特性就是多态,也就是说我们可以针对于基类来编程从而降低程序的耦合度。
以Java来说,常常就是通过继承的方式,来实现这种效果,就像下面的代码里做的一样:

public class Demo {
    public static void main(String[] args) {
          Animal [] animals = new Animal[2];
          animals[0] = new Tiger();
          animals[1] = new fish();
          for (Animal animal : animals) {
            animal.breath();
        }
    }
}

abstract class Animal {
    abstract void breath();
}

class Tiger extends Animal{

    @Override
    void breath() {
        // TODO Auto-generated method stub

    }

}

class fish extends Animal{

    @Override
    void breath() {
        // TODO Auto-generated method stub

    }   
}

这样的代码是很常见的,而它们之所以能够编译通过,是因为程序在编译期时,
上述代码中的Tiger和Fish类型都会被向上转型称为基类,也就是说其实它们自身的类型信息会丢失。
但是呢,在程序进入运行期后,当我们调用”animal.breath”,它们却能准确的找到所属类型当中的方法进行调用。
这到底是为什么呢?其实原因我们在JAVA 笔记(一)里已经说过,就是因为运行时绑定(即动态绑定)机制。

所以,这里我们就可以进一步分析,既然程序在运行时才选择最合适的方法进行绑定。
那么,很自然的就可以联想到,要选择方法进行绑定,前提当然的是能在程序运行时获取到类型的方法列表,继承结构等信息。
这也就引出了我们下面要说的东西:运行时类型信息(Run-time Type Information)。

  • load class (类的装载过程)

实际上,我们在JAVA 笔记(一)当中总结类的初始化顺序的时候,已经提到过关于类的装载。这里我们再次总结一下:

  • Java的程序在其开始运行之前,并不会被完全加载。所有的类都是在其第一次被使用时,动态的加载到内存当中。
  • 所谓的第一次被使用时加载。也就是指当程序创建第一个对类的静态成员的引用的时候,就会被加载。
  • 对一个类进行装载的工作过程很简单:类装载器(ClassLoader)会首先检查类是否已经被加载过;
    如果检查到之前该类型还没有被进行过装载,则根据类名查找对应的.class文件将其装载进内存当中。

简单的来说,类的装载过程就是这样。但是这里我可以关注到另一个关键的信息:
与我们本文中说到的运行时类型信息对应,那么有没有一个编译时类型信息呢?
其实不难想象肯定是有的,因为“羊毛出在羊身上”。实际上当一个类文件经过编译,其包含的信息就被装载进编译后的字节码文件中了。
所以我们可以将.class文件看做是类的“编译时类型信息”;而当期在运行时被类装载器加载后,就引出了我们马上要说到的另一个概念。

  • “class of classes” 类的类

前面我们说到类的字节码文件可以被我们视作类的编译时类型信息,那么当其被装载过后又会怎么体现呢?
其实这也就是我们本文的重点:运行时类型信息。编译时的类型信息以“.class文件”作为载体。
那么,很明显同理来说,运行时类型信息自然也需要一个载体,而这个载体就是”Class”类型对象。

我们知道一个Java程序实际上就是由一个个的类(即class)组合而成的,但这里的此”Class”并非 彼“class”。
更形象的比喻来说,”Class对象”又被称作”class of classes“,即”类的类“。
之所以我们进行这样的比喻,实际上正是因为每一个类都会有一个”Class对象”;
每当我们编写一个新类,就会产生一个新的”Class对象”(被保存在同名的.class文件)。

事实上,“Class对象”的作用 就是用来创建对应类型的所有“常规”对象的。
(所以我们可以把这个对象看做是“雕版”,我们程序中创建使用的对象即印刷出的“百元大钞”)

更加细致的来说,也就是当类被类装载器装载进内存之后,就会有一个对应的”Class”类型对象进入内存。
被装载进的这个“Class对象”保存该类的所有自身信息,而JVM也正是通过这个对象来进行RTTI(程序运行时类型检查)工作的。

就以我们前面说到的“向下转型”的工作来说,其实也就是通过这样的方式来实现类型检查的。
通过一个简单的例子,我们可以更好的理解这种检查工作。假设我们的程序中有这样一个方法:

public class Demo {

    public static <T> void test(T t){
        Demo d = (Demo) t;
    }

}

这段程序在编译时是能够通过,因为程序在编译器并不能确定被传入的t的类型,这是在程序运行时才决定的。
那么,假设我们在运行时调用该方法,传入一个String类型的参数,会得到什么结果?

    public static void main(String[] args) {
         test("123");
    }

没错,程序运行该段代码的时候,会得到一个运行时异常:ClassCastException。
注意了,这时我们就值得思考了?为什么JVM在运行时能够判断出String类型不能被转换为Demo类型。
答案当然就是,JVM能够通过某种方式在运行时去获取到这两种类型的类型信息。而这种方式就是通过“Class对象”

我们从Class类的API文档当中,选取一些比较常用的具有代表性的方法接口来看一看:

  • static Class< ? > forName(String className) 返回与带有给定字符串名的类或接口相关联的 Class 对象。
  • ClassLoader getClassLoader() 返回该类的类加载器。
  • Class< ? > getComponentType() 返回表示数组组件类型的 Class。
  • Constructor< T > getConstructor(Class< ? >… parameterTypes) 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
  • Field getField(String name) 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
  • Class< ? >[] getInterfaces() 确定此对象所表示的类或接口实现的接口。
  • Method[] getMethods () 返回一个包含某些 Method 对象的数组。
  • String getName() 以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
  • Package getPackage() 获取此类的包。
  • Class< ? super T > getSuperclass() 返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。

同上上面截取的部分接口列表我们已经可以发现,一个类的所有信息其实我们都可以在其对应的”Class对象”里找到。
所以当我们了解了原理了之后,现在自己也可以模仿JVM在上面报出类型转换异常的代码处所做的检查工作。

我们先来看一段比较有趣的测试代码:

public class Demo {
    public static void main(String[] args) {
        Father f1 = new Father();
        test(f1);
        Father f2 = new Son();
        test(f2);
    }

    public static <T> void test(T t) {
        // Son s = (Son) t;
        Class clazzT = t.getClass();
        System.out.println("T.className ==>> " + clazzT.getSimpleName());
    }

}

class Father {}
class Son extends Father {}

这段测试程序的运行结果,其实还是比较有意思:

T.className ==>> Father
T.className ==>> Son

我们注意到,虽然引用f2出现了“父类引用指向子类对象的情况”。但其实它的Class对象可以清楚的知道它实际是“Son”类型。
那么,我们其实可以很轻松的通过“Class对象”来模仿JVM对类型转换所做的检查工作:

public class Demo {
    public static void main(String[] args) {
        Father f1 = new Father();
        test(f1);
        Father f2 = new Son();
        test(f2);
    }

    public static <T> void test(T t) {
        // Son s = (Son) t;
        Class clazzT = t.getClass();        
        Class clazzTarget = Son.class;

        if(clazzT.equals(clazzTarget)){
            System.out.println("可以转换");
        }else{
            System.out.println("不能转换");
        }
    }

}

class Father {}
class Son extends Father {}

运行我们修改后的代码,发现输出结果为:

不能转换
可以转换

由此,我们也如我们所了解到的那样,实际正是通过“Class对象”来完成了程序的运行时类型检查工作。

  • Class对象的获取方式

前面我们了解了Class对象带来的好处,那么,在程序当中我们可以通过哪些方式来获取Class对象呢?

  • new Object().getClass();

new一个对象这种工作,我们恐怕已经做过无数回了。而要获取new出的对象的“模板”对象,就是通过obj.getClass():

public class Demo {
    public static void main(String[] args) {
       Class clazzDemo =  new Demo().getClass();
    }
}
  • Class.forName(String className);

第二种方式,就是通过Class类的成员方法”forName”来获取。这种方式需要注意的就是处理异常。
因为根据类名来查找并获取”Class对象”,就自然要考虑到查找不到传入的类名对应的对象的情况。

public class Demo {
    public static void main(String[] args) {
        try {
            Class clazzDemo = Class.forName("Demo");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
  • 类字面常量 className.class

类字面常量是另一种获取Class对象的方式。与使用forName()方法相比,它的好处是:更加简单和安全。
之所以更加安全是因为,它在编译时就会受到检查。由此它也可以避免Try-catch语句块。

public class Demo {
    public static void main(String[] args) {
            Class clazzDemo = Demo.class;
    }
}
  • Class.forName 与 类字面常量的特点比较

虽然我们说过这两种方式都可以获取到类运行时信息”Class对象”,但同时它们也具备一些不同的特点。
要了解这之间的差别,我们首先要弄清楚当使用一个类时所作的准备工作的步骤,事实上这个步骤分为三步:

  • 加载。即类装载器在指定路径下查找对应的字节码文件,并从这些字节码中创建出一个Class对象。
  • 链接。即验证类中的字节码,为静态域分配存储区域;如果有需要,还将解析这个类创建的对其它类的引用。
  • 初始化。也就是我们常说的“类的初始化工作(包括静态域,成员变量,构造器等等)。

Class.forName 与 类字面常量的区别就在于“初始化”。对于类字面常量来说,“初始化工作”拥有足够的“惰性”。
我们仍然先通过一段代码,来看一看具体的体现形式:

public class Demo {

    public static void main(String[] args) {
        try {
            Class clazzTest = Class.forName("Test");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

class Test {
    static {
        System.out.println("静态初始化子句执行");
    }
}

运行以上代码,程序的输出结果将是:

静态初始化子句执行

接着,我们来看看如果使用类字面常量来获取Class对象,会是什么情况?

public class Demo {

    public static void main(String[] args) {
        Class clazzTest = Test.class;
    }
}

class Test{
    static {
        System.out.println("静态初始化子句执行");
    }
}

根据打印结果,我们会发现Test类的“初始化”并没有执行。这恰好印证了我们说的“惰性”。
那么,这个所谓的“惰性”究竟被延迟到了什么时候呢?答案就是:延迟到了对静态方法或者非常数的静态域进行首次访问的时候。

也就是说,假设我们有一个如下的测试类:

class Test {
    static int x = 100;
    static final int x1 = 100;
    static final int x2 = new Random().nextInt();

    static {
        System.out.println("静态初始化子句执行");
    }

    static void test(){

    }   
}

那么,就只有当“x”或者”test()”方法被首次访问时,才会进行初始化工作。
而“x1”即使被访问也不会进行初始化,因为这样定义的域是“编译时常量”,不需要初始化就可以访问。
而“x2”的访问仍然会引发类的初始化,因为虽然这是一个常量,但是是我们在JAVA 笔记(一)里说到过的运行时常量。

由此,你可能已经发现,相对于使用Class.forName的方式来说,其实类字面常量显然有更多的好处:
比如更加安全,更加简洁明了,而且拥有足够的初始化“惰性”。那我们为什么还要使用Class.forName呢?
你是否还记得,我们说类字面常量之所以更安全是因为它在编译时就会受到检查。即类型在编译时就已被明确。
但现实的情况是,有些时候我们要使用到的类型在程序的编写时期是无法确定的。
这个时候Class.forName就有了用武之地,即我们常说的类的放射,我们马上就会接着说道。

  • 类的反射

反射的根本就是在程序运行时,动态的选择适合的类型使用。也就是我们说的在编写代码时,无法确定类型的时候。
其实反射的原理很简单,我们借助《Thinking in java》当中的一段文字可以很好的得以了解:
这里写图片描述
但概念性的东西说到底都还是挺乏味的,我们可以通过一个简单但具有一定代表性的例子来加深理解。

举例来说,假设我们为一个工厂编写生产汽车的类。那么,很面显的,汽车可能具有不同的类型。
也就是说,在真正开始生产之前,我们无法确定采用哪种方式生产汽车。
假设生产不同类型汽车的部门都属于都一个工厂旗下,那情况还比较容易处理一些。
例如,该工厂可以生产轿车和卡车,这两种类型的汽车的生产由同一工厂的不同部门负责。

public class Factory {
    void produce(ProduceDepartment pd) {
        pd.produce();
    }
}

interface ProduceDepartment {
    void produce();
}

class CarProduceDepartment implements ProduceDepartment {

    @Override
    public void produce() {
        System.out.println("轿车生产");
    }

}

class TruckProduceDepartment implements ProduceDepartment {

    @Override
    public void produce() {
        System.out.println("卡车生产");
    }

}

由于生产的部门都属于同一家工厂,虽然不确定在运行时的调用类型,但我们通过以上的代码编写方式,已经足够控制。

但假设一下,假设汽车的生产由不同的生产厂商完成。也就是说,你根本无法确定在实际生产时,有哪些生产厂商。
对应在编程的思想中来说,也就是说,你在编写程序的时候,根本就不知道有哪些类型能够提供给你。
所以,情况就变得有些复杂了。这个时候,就是反射站出来装逼的时候。我们可以修改我们的代码如下:

public class Factory {

    @SuppressWarnings("unchecked")
    void produce(String className) {
        Class<ProduceStandard> clazzPS = null;
        try {
            // 通过反射查询到对应的类的Class对象
            clazzPS = (Class<ProduceStandard>) Class.forName(className);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        if (clazzPS != null) {
            try {
                // 通过Class对象生产我们要使用的常规对象
                ProduceStandard ps = clazzPS.newInstance();
                ps.produce(); // 生产
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
}

interface ProduceStandard {
    void produce();
}

这下牛逼了。实际我们做的工作原理仍然很简单,我声明生产汽车的规范(接口).
之后任何生产厂商都可以根据该规范去具体实现。我们在运行时通过类名(即生产厂商的实现)去查找到你的实现。
然后通过newInstance创建可以使用的常规对象,从而来调用并进行生产。这就是所谓的反射。

相信到此你就明白了所谓的反射的原理,实际上反射在实际的编码工作中,最常见的就是驱动程序。
最最最最最最最熟悉的,应该就是数据库驱动jdbc的使用了。以mysql的访问来说,我们在初始化驱动的时候,都会用到这样的代码:

 Class.forName("com.mysql.jdbc.Driver")

现在我们总算知道它的用意了。很显然,Java的设计者在设计的时候肯定不会知道之后具体有哪些数据库需要实现驱动。
所以,使用反射就是最合适的了。

  • instanceof 与 Class.isInstance(Object obj)

实际上,Java当中对于RTTI-运行时类型检查还有另一种常用的方式,即使用instanceof进行类型判断。

public class Demo {

    static <T> void f(T t){
        if(t instanceof Object){

        }
    }
}

而通过Class对象,也可以完成这样的判断。即通过Class.isInstance(Object obj)方法来进行判断。
我们来看一下Java的API文档当中对于该方法的说明是怎么样的:

判定指定的 Object 是否与此 Class 所表示的对象赋值兼容。此方法是 Java 语言 instanceof 运算符的动态等效方法。

如果指定的 Object 参数非空,且能够在不引发 ClassCastException 的情况下被强制转换成该 Class 对象所表示的引用类型,则该方法返回 true;否则返回 false。

所以说,我们下面代码中使用的两种判断方式,实际上效果是等价的:

public class Demo {

    static <T> void f(T t){
        // 1.
        Father.class.isInstance(t);
        // 2.
        if(t instanceof Father){

        }
    }
}

class Father{};
class Son extends Father{};

OK,到此,我们对于Java当中的运行时类型检查机制(RTTI)也就有了了解。相信对于我们的使用会有一定的帮助。

【C++】运行时类型识别RTTI与反射详解 RTTI RTTI(Run-Time Type Information)运行时类型识别的英文缩写,它提供了运行时确定对象类型的方法。面向对象的编程语言,像C++,Java,delphi都提供了对RTTI的支持。 本文将描述 RTTI 的概念、简略介绍 RTTI 的一些背景知识、并通过具体例子和代码介绍什么时候使用以及如何使用 RTTI的两个重要运算符 typeid 和 dynamic_cast的使用方法。 背景知识 其实,RTTI 在C++中并不是什么新的东西,它早在十多年以前就已经出现了。但是大多数 阅读详情

相关推荐

开源项目 ruoyi-sso-oauth2(一)环境配置

Ruoyi若依实现单点登录SSO、oauth2认证

Xiaoweidumpb 9683

运行时类型检查

运行时类型信息(run-time type information)通常记做RTTI。 在C++primer第五版中,译作运行类型识别(run-time type identification)。 运行时类型信息包括三部分: 1)一个运算符dynamic_cast,给它一个指向某某对象的基类指针,它能得到一个到这个对象的派生类指针。只有在被指对象确实属于所指明的派生类时,运算符dyn

waponx的专栏 1145

RTC 实时时钟实验

如果在 RTC_CR 寄存器中设置了相应的允许位,则在每个TR_CLK 周期中 RTC 产生一个中断(秒中断)。void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data) // 往备份区域写用户数据的函数 (这个函数的第一个参数就是寄存器的标号了,这个是通过宏定义定义的)存储在 RTC_ALR 寄存器中的可编程时间相比较,如果 RTC_CR 控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。寄存器操作完成,并同步之后,设置秒钟中断。

m0_55996456的博客 1205

java的rtti机制

1、RTTI: 运行时类型信息可以让你在程序运行时发现和使用类型信息。 在Java中运行时识别对象和类的信息有两种方式:传统的RTTI,以及反射。下面就来说下RTTI。 RTTI:在运行时,识别一个对象的类型。但是这个类型在编译时必须已知。 下面通过一个例子来看下RTTI的使用。这里涉及到了多态的概念:让代码只操作基类的引用,而实际上调用具体的子类的方法,通常会创建一个具体的对象(Circl...

Faith的博客 1862

私有云平台搭建——OpenStack

私有云平台搭建——OpenStack 搭建过程

2301_79739036的博客 3089

ESM2蛋白预训练模型 蛋白质、氨基酸向量表示

参考: https://github.com/facebookresearch/esm https://huggingface.co/facebook/esm2_t33_650M_UR50D https://esmatlas.com/resources?action=fold tokenizer_对输入蛋白会头尾添加cls、eos特殊字符,占两个字符长度 参考:https://github.com/facebookresearch/esm 直接clone下来代码

weixin_42357472的博客 1万+

java的rtti_JAVA RTTI

基础类可接收我们发给派生类的任何消息,因为两者拥有完全一致的接口。我们要做的全部事情就是从派生上溯造型,而且永远不需要回过头来检查对象的准确类型是什么。所有细节都已通过多态性获得了完美的控制。但经过细致的研究,我们发现扩展接口对于一些特定问题来说是特别有效的方案。可将其称为“类似于”关系,因为扩展后的派生类“类似于”基础类——它们有相同的基础接口——但它增加了一些特性,要求用额外的方法加以实现。如...

weixin_39952031的博客 310

基于Python的CT骨料图像分割与STL批量导出完整指南

本文介绍了一套完整的Python解决方案,用于CT骨料图像的分割与STL导出。针对CT图像中颗粒粘连、噪声伪影等技术难点,提出基于分水岭算法的分割策略,结合距离变换与标记控制实现颗粒分离。内容包括环境配置、数据读取与预处理、Otsu阈值分割、分水岭算法实现、表面提取与STL导出等关键步骤。教程提供详细代码及解释,帮助读者从CT体数据出发,最终生成每个颗粒的三维网格文件,便于后续定量分析和数值模拟。

huanghm88的专栏 235

java的rtti_Java进阶-RTTI

运行时类型识别(RTTI, Run-Time Type Identification)是Java中非常有用的机制,在Java运行时,RTTI维护类的相关信息。多态(polymorphism)是基于RTTI实现的。RTTI的功能主要是由Class类实现的。Class类Class类是"类的类"(class of classes)。如果说类是对象的抽象和集合的话,那么Class类就是对类的抽象和集合。每...

weixin_29479561的博客 279

49、Linux内核内存管理:MGLRU、DAMON与OOM杀手详解

本文详细解析了Linux内核内存管理中的三大核心机制:MGLRU(多代LRU)页面追踪与回收机制、DAMON数据访问监控工具及其在内存优化中的应用,以及OOM(内存不足)杀手的工作原理和触发方式。同时,文章还介绍了VM overcommit_memory策略的设置及其对内存分配的影响,帮助开发者和系统管理员更好地理解Linux内存管理机制,从而优化系统性能和稳定性。

dropout6artist的博客 107

Agent Harness Engineering: AI Agent 执行管控与安全沙箱 原理与最佳实践

我们正站在计算范式转移的历史节点上。2024-2026 年间,AI 系统从被动的内容生成器(Generative AI)演变为主动的行动执行者(Agentic AI)。这一转变的根本特征是:根据 2026 年初的行业数据:然而,能力的提升伴随着风险的指数级增长。2024-2026 年间发生的多起标志性安全事件揭示了 Agent 系统的脆弱性:案例 1:Slack AI 数据外泄事件(2024 年 8 月)案例 2:制造业供应链攻击(2026 年 Q3)案例 3:Arup 深度诈骗案(2026 年 9 月)这

AI天才研究院 1667

java的动态绑定机制

调用 a.sound() 时,由于动态绑定机制,会调用 Dog 类的 sound 方法,而不是 Animal 类的 sound 方法,这就是多态性的体现。​ Java的动态绑定机制是指程序在运行时,根据对象的实际类型来决定调用哪个方法的过程。表现:多态性体现在父类引用可以指向子类对象,而调用方法时会根据对象的实际类型来决定调用哪个方法,这就是动态绑定的过程。没有动态绑定,就无法在运行时根据对象的实际类型来调用正确的方法。总之,动态绑定是多态性实现的基础,它们之间是相辅相成的关系。

qq_48973099的博客 409

Python爬虫实战:微信小程序内容采集的全面指南

在移动互联网时代,微信小程序已成为企业和个人提供服务的重要渠道。小程序中包含了大量有价值的信息,但微信官方并未提供便捷的数据获取接口。本文将详细介绍如何使用Python爬虫技术采集微信小程序内容,包括最新技术方案、完整代码实现以及应对各种反爬机制的策略。小程序运行在微信封闭环境中,无法直接访问数据通信主要通过HTTPS加密传输内容动态加载,依赖JavaScript渲染微信有严格的反爬机制。

2201_76125261的博客 3115

Java中运行时类型识别RTTI

在Java中,并不是所有的类型信息都能在编译阶段明确,有一些类型信息需要在运行时才能确定,这种机制被称为RTTI,英文全称为Run-Time Type Identification,即运行时类型识别,有没有一点“知行合一”的味道?运行时类型识别主要由Class类实现。 一、class 和Class 在Java中,我们常用“class”(首字母为小写的c)关键字来定义一个类,说这个类是对某一类对...

FeelTouch Labs 719

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

java的RTTI

在Java中,RTTI表现在:1。Class对象,是RTTI的核心,每个类都有一个class对象。每当编写并且编译一个新类,就会产生一个Class对象(被保存在同名的.class文件当中)2。instanceof 关键字用于检查对象是不是某个特定类型的实例。3。强制类型转换,如:Parent object = new Child();Child child = (Child)object;至于实现机制,根据JVM实现的不同,没有固定的答案。

FG2006的专栏 6701

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

java 运行时类型_Java基础之RTTI 运行时类型识别

运行时类型识别(RTTI, Run-Time Type Identification)是Java中非常有用的机制,在Java运行时,RTTI维护类的相关信息。多态(polymorphism)是基于RTTI实现的。RTTI的功能主要是由Class类实现的。Class类Class类是"类的类"(class of classes)。如果说类是对象的抽象和集合的话,那么Class类就是对类的抽象和集合。每...

weixin_39758696的博客 272

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Java的RTTI运行时类型识别机制(转)

举例讲解Java的RTTI运行时类型识别机制 更新时间:2016年05月09日 09:01:07 作者:arthinking 这篇文章主要介绍了Java的RTTI运行时类型识别机制,包括泛化的Class引用以及类型检查instanceof等知识点,需要的朋友可以参考下 1、RTTI: 运行时类型信息可以让你在程序运行时发现和使用类型信息。 在Java中运行时识别对象和类的信息有两种方式:传统的RTTI,以及反射。下面就来说下RTTI。 RTTI:在运行时,识别一个对象的类型。但是这个类型...

htj10的博客 195

RTTI:运行时类型识别

RTTI:运行时类型识别参考链接:https://www.cnblogs.com/JohnTsai/p/4821287.html1、什么是RTTI应用场景2、获取Class对象的三种方法 参考链接:https://www.cnblogs.com/JohnTsai/p/4821287.html 在《Java编程思想》一书中,学习泛型的时候提到了一个很重要的点,称之为RTTI,即运行时类型识别 经过自...

Justmemoryl 338

Java运行时类型信息RTTI

应用程序在运行的时候获取一个对象的类型信息的技术称之为运行时类型信息RTTI(Run-Time Type Identification)。RTTI是C++的一个概念,Java中的RTTI是在《think in java》这本书中作者提出来的,官方文档里面并没有RTTI这个概念。作为学习者不应该纠结于一项技术的命名,而应该关注命名所指代的具体技术或者思想,RTTI指代的是一组在运行时获取对象类型信息...

烧水匠 252

RTTI运行时类型识别

RTTI(Run-Time Type Identification),通过运行时类型信息程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。。面向对象的编程语言,像C++,Java,delphi都提供了对RTTI的支持。 本文主要介绍C++的RTTI以及MFC相关的RTTI。 1、C++ RTTI提供了以下两个非常有用的操作符: 1)typeid操作符,返回指针和引用

baidu_27396537的博客 402

java rtti_举例讲解Java的RTTI运行时类型识别机制

1、RTTI:运行时类型信息可以让你在程序运行时发现和使用类型信息。在Java中运行时识别对象和类的信息有两种方式:传统的RTTI,以及反射。下面就来说下RTTI。RTTI:在运行时,识别一个对象的类型。但是这个类型在编译时必须已知。下面通过一个例子来看下RTTI的使用。这里涉及到了多态的概念:让代码只操作基类的引用,而实际上调用具体的子类的方法,通常会创建一个具体的对象(Circle,Squar...

weixin_29143935的博客 230

JAVA是如何在运行时确定对象类型?

JAVA是如何在运行时确定对象类型? 一、RTTI 在运行时确定对象类型,俗称RTTI(Run-Time Type Information),即运行时类型识别的信息,使用java官方语言则为:Java在运行时能够获得或判断某个对象的类型信息。 二、JAVA在运行时,识别对象和类信息的方式: 转型 利用class对象 反射机制 三、识别对象和类信息的方式解释: 转型 在程序运行时检查父类型的引用是否可以指向子类型的对象,即确保类型向上转换安全。 样例一: abstract class Shape

weixin_41806512的博客 1284

C++运行时类型信息 (RTTI)

RTTI是”Runtime Type Information”的缩写,意思是运行时类型信息,它提供了运行时确定对象类型的方法。RTTI并不是什么新的东西,很早就有了这个技术,但是,在实际应用中使用的比较少而已。而我这里就是对RTTI进行总结,今天我没有用到,并不代表这个东西没用。学无止境,先从typeid函数开始讲起。

人无远虑,必有近忧 1039

运行时类型信息(RTTI + 反射)

运行时类型信息使得你可以在程序运行时发现和使用类型信息。 Java是如何让我们在运行时识别对象和类的信息的,主要有3种方式 “传统的”RTTI,它假定我们在编译时已经知道了所有的类型,比如Shape s = (Shape)s1; “反射”机制,它运行我们在运行时发现和使用类的信息,即使用Class.forName()。 关键字instanceof,它返回一个bool值,它保持了类型的概念,它指的是...

zhaosansao的博客 481
上一篇: JAVA 笔记(三) 从源码深入浅出集合框架
下一篇: JAVA 笔记(五) ThreadPoolExecutor 源码剖析
LaterEqualsNever
博客等级 码龄12年 297粉丝 61原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值