十九、类型信息(1)

news2025/1/13 13:54:12

本章概要

  • 为什么需要 RTTI

RTTI(RunTime Type Information,运行时类型信息)能够在程序运行时发现和使用类型信息

RTTI 把我们从只能在编译期进行面向类型操作的禁锢中解脱了出来,并且让我们可以使用某些非常强大的程序。对 RTTI 的需要,揭示了面向对象设计中许多有趣(并且复杂)的特性,同时也带来了关于如何组织程序的基本问题。

本章将讨论 Java 是如何在运行时识别对象和类信息的。主要有两种方式:

  1. “传统的” RTTI:假定我们在编译时已经知道了所有的类型;
  2. “反射”机制:允许我们在运行时发现和使用类的信息。

为什么需要 RTTI

下面看一下我们已经很熟悉的一个例子,它使用了多态的类层次结构。基类 Shape 是泛化的类型,从它派生出了三个具体类: CircleSquareTriangle(见下图所示)。

在这里插入图片描述

这是一个典型的类层次结构图,基类位于顶部,派生类向下扩展。面向对象编程的一个基本目的是:让代码只操纵对基类(这里即 Shape )的引用。这样,如果你想添加一个新类(比如从 Shape 派生出 Rhomboid)来扩展程序,就不会影响原来的代码。在这个例子中,Shape 接口中动态绑定了 draw() 方法,这样做的目的就是让客户端程序员可以使用泛化的 Shape 引用来调用 draw()draw() 方法在所有派生类里都会被覆盖,而且由于它是动态绑定的,所以即使通过 Shape 引用来调用它,也能产生恰当的行为,这就是多态。

因此,我们通常会创建一个具体的对象(CircleSquare 或者 Triangle),把它向上转型成 Shape (忽略对象的具体类型),并且在后面的程序中使用 Shape 引用来调用在具体对象中被重载的方法(如 draw())。

代码如下:

import java.util.stream.*;

abstract class Shape {
    void draw() {
        System.out.println(this + ".draw()");
    }

    @Override
    public abstract String toString();
}

class Circle extends Shape {
    @Override
    public String toString() {
        return "Circle";
    }
}

class Square extends Shape {
    @Override
    public String toString() {
        return "Square";
    }
}

class Triangle extends Shape {
    @Override
    public String toString() {
        return "Triangle";
    }
}

public class Shapes {
    public static void main(String[] args) {
        Stream.of(new Circle(), new Square(), new Triangle()).forEach(Shape::draw);
    }
}

输出结果:

在这里插入图片描述

基类中包含 draw() 方法,它通过传递 this 参数传递给 System.out.println(),间接地使用 toString() 打印类标识符(注意:这里将 toString() 声明为 abstract,以此强制继承者覆盖该方法,并防止对 Shape 的实例化)。如果某个对象出现在字符串表达式中(涉及"+"和字符串对象的表达式),toString() 方法就会被自动调用,以生成表示该对象的 String。每个派生类都要覆盖(从 Object 继承来的)toString() 方法,这样 draw() 在不同情况下就打印出不同的消息(多态)。

这个例子中,在把 Shape 对象放入 Stream<Shape> 中时就会进行向上转型(隐式),但在向上转型的时候也丢失了这些对象的具体类型。对 stream 而言,它们只是 Shape 对象。

严格来说,Stream<Shape> 实际上是把放入其中的所有对象都当做 Object 对象来持有,只是取元素时会自动将其类型转为 Shape。这也是 RTTI 最基本的使用形式,因为在 Java 中,所有类型转换的正确性检查都是在运行时进行的。这也正是 RTTI 的含义所在:在运行时,识别一个对象的类型。

另外在这个例子中,类型转换并不彻底:Object 被转型为 Shape ,而不是 CircleSquare 或者 Triangle。这是因为目前我们只能确保这个 Stream<Shape> 保存的都是 Shape

  • 编译期,stream 和 Java 泛型系统确保放入 stream 的都是 Shape 对象(Shape 子类的对象也可视为 Shape 的对象),否则编译器会报错;
  • 运行时,自动类型转换确保了从 stream 中取出的对象都是 Shape 类型。

接下来就是多态机制的事了,Shape 对象实际执行什么样的代码,是由引用所指向的具体对象(CircleSquare 或者 Triangle)决定的。这也符合我们编写代码的一般需求,通常,我们希望大部分代码尽可能少了解对象的具体类型,而是只与对象家族中的一个通用表示打交道(本例中即为 Shape)。这样,代码会更容易写,更易读和维护;设计也更容易实现,更易于理解和修改。所以多态是面向对象的基本目标。

但是,有时你会碰到一些编程问题,在这些问题中如果你能知道某个泛化引用的具体类型,就可以把问题轻松解决。例如,假设我们允许用户将某些几何形状高亮显示,现在希望找到屏幕上所有高亮显示的三角形;或者,我们现在需要旋转所有图形,但是想跳过圆形(因为圆形旋转没有意义)。这时我们就希望知道 Stream<Shape> 里边的形状具体是什么类型,而 Java 实际上也满足了我们的这种需求。使用 RTTI,我们可以查询某个 Shape 引用所指向对象的确切类型,然后选择或者剔除特例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1137135.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Active learning Tiny Review for autonomous driving

Introduction 阅读某一特定主题的一本书不会使你成为专家&#xff0c;阅读多本包含相似内容的书也不会。真正掌握一项技能或领域的知识需要来自多样化信息源的大量信息。 这对于自动驾驶和其他人工智能技术同样适用。 负责自动驾驶功能的深度神经网络需要经过详尽的训练&#…

ES 数据迁移最佳实践

ES 数据迁移最佳实践与讲解 数据迁移是 Elasticsearch 运维管理和业务需求中常见的操作之一。以下是不同数据迁移方法的最佳实践和讲解&#xff1a; 一、数据迁移需求梳理 二、数据迁移方法梳理 三、各方案对比 方案 优点 缺点&#xff08;限制&#xff09; 适用场景 是否有…

Lua脚本语言

1. 概念 Lua&#xff08;发音为"loo-ah"&#xff0c;葡萄牙语中的"lua"意为月亮&#xff09;是一种轻量级的、高效的、可嵌入的脚本编程语言。官网Lua最初由巴西计算机科学家Roberto Ierusalimschy、Waldemar Celes和Luiz Henrique de Figueiredo于1993年开…

看完这篇 教你玩转渗透测试靶机Vulnhub——Hacksudo: Aliens

Vulnhub靶机Bluemoon: 2021渗透测试详解 Vulnhub靶机介绍&#xff1a;Vulnhub靶机下载&#xff1a;Vulnhub靶机安装&#xff1a;Vulnhub靶机漏洞详解&#xff1a;①&#xff1a;信息收集&#xff1a;②&#xff1a;数据库后台传木马&#xff1a;③&#xff1a;反弹shell&#x…

免费活动-11月4日敏捷武林上海站 | Scrum.org CEO 亲临现场

​​​​​​​ 活动介绍 过去的几年里&#xff0c;外界的风云变幻为我们的生活增添了一些不一样的色彩。在VUCA世界的浪潮里&#xff0c;每一个人都成为自己生活里的冒险家。面对每一次的变化&#xff0c;勇于探索未知&#xff0c;迎接挑战&#xff0c;努力追逐更好的自己。…

实现地址转换的硬件机构

一、基本地址变换机构 1.硬件&#xff1a; 设置一个页表寄存器&#xff0c;存放页表在内存中的起始地址与页表长度。 2.执行过程&#xff1a; 进程未执行时&#xff0c;页表起始地址和长度存放在进程控制块(PCB)中;进程被调度时&#xff0c;OS内核会将其放入页表寄存器中。 3.具…

海外广告投放必看,如何使用Quora广告开拓新流量市场?

虽然在Quora 上学习广告相对容易&#xff0c;但需要大量的试验和错误才能找出最有效的方法。一些广告技巧可以让您的工作更有效率。这篇文章将介绍如何有效进行quora广告投放与有价值的 Quora 广告要点&#xff0c;这将为您节省数万美元的广告支出和工作时间&#xff01;往下看…

postgresSQL 数据库本地创建表空间读取本地备份SQL文件

使用pgAdmin4&#xff0c;你安装PG得文件夹****/16/paAdmin 4 /runtime/pgAdmin4.exe 第一步&#xff1a;找到Tablespaces 第二步&#xff1a;创建表空间名称 第三步&#xff1a;指向数据文件 第四步&#xff1a;找到Databases&#xff0c;创建表空间 第五步&#xff1a;输入数…

SpringBoot依赖和代码分开打包

前言 在公司的项目中&#xff0c;一个SpringBoot工程可能就上百MB&#xff0c;这时候当线上网速不佳的时候&#xff0c;部署起来就十分的痛苦了。。经常等好久才能上传完毕&#xff0c;接下来我来教大家一个SpringBoot工程代码和依赖分开打包的方法。这种方法将依赖和代码分开…

身份证号码,格式校验:@IdCard(Validation + Hutool)

目标 自定义一个用于校验 身份证号码 格式的注解IdCard&#xff0c;能够和现有的 Validation 兼容&#xff0c;使用方式和其他校验注解保持一致&#xff08;使用 Valid 注解接口参数&#xff09;。 校验逻辑 有效格式 符合国家标准。 公民身份号码按照GB11643&#xff0d;…

NOIP2023模拟2联测23 分神

题目大意 有 n n n个矩形&#xff0c;每个矩形的四条边都平行于坐标轴。对于一个矩形&#xff0c;它的左下角坐标为 ( x 1 , y 1 ) (x_1,y_1) (x1​,y1​)&#xff0c;右上角坐标为 ( x 2 , y 2 ) (x_2,y_2) (x2​,y2​)&#xff0c;包含了所有满足 x 1 ≤ x ≤ x 2 , y 1 ≤ …

app分发的一些流程2

应用分发的流程通常包括以下步骤&#xff1a; 开发应用程序&#xff1a;首先&#xff0c;您需要开发您的应用程序。这包括编写代码、设计用户界面、测试应用程序等等。确保您的应用程序符合各个应用商店的规范和要求&#xff0c;以确保顺利通过审核。 准备应用材料&#xff1…

Android 13.0 自定义仿小米全面屏手势导航左右手势滑动返回UI效果

1.概述 在13.0的系统产品开发中,对于设置默认系统手势的左右滑动返回UI,系统默认的是比较简单,产品需求要求仿小米华为的左右手势返回UI样式的定制,所以需要找到绘制手势返回UI的相关代码,然后自定义手势导航左右滑动返回的相关UI就可以了 接下来就来实现手势导航做好手势…

windows殺死端口

netstat -ano | findstr 8081 taskkill /F /PID taskkill /F /PID 16624

796. 子矩阵的和(左上角前缀和)

题目&#xff1a; 796. 子矩阵的和 - AcWing题库 思路&#xff1a; 1.暴力搜索&#xff08;搜索时间复杂度为O(n2)&#xff0c;很多时候会超时&#xff09; 2. 前缀和&#xff08;左上角前缀和&#xff09;&#xff1a;本题特殊在不是直接求前n个数的和&#xff0c;而是求…

竞赛 深度学习图像分类算法研究与实现 - 卷积神经网络图像分类

文章目录 0 前言1 常用的分类网络介绍1.1 CNN1.2 VGG1.3 GoogleNet 2 图像分类部分代码实现2.1 环境依赖2.2 需要导入的包2.3 参数设置(路径&#xff0c;图像尺寸&#xff0c;数据集分割比例)2.4 从preprocessedFolder读取图片并返回numpy格式(便于在神经网络中训练)2.5 数据预…

Leo赠书活动-03期 【ChatGPT 驱动软件开发:AI 在软件研发全流程中的革新与实践 】

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠书活动专栏 ✨特色专栏&#xff1a;…

Java学习 习题 1.

一、 1.2. 3. 4. 5. 二、 1. 2. 3. 4. 5. 6. 7. 8.

【Java技术专题】「入门到精通系列教程」深入探索Java特性中并发编程体系的原理和实战开发指南( 实现可伸缩IO专题)— 上

深入探索Java特性中并发编程体系的原理和实战开发指南&#xff08; 实现可伸缩IO专题&#xff09; 总体内容概览可扩展的网络服务分布式对象传统的阻塞式网络服务每个请求或连接可以在独立的线程中进行处理Server服务处理请求类Handler处理逻辑类优点缺点 可扩展性目标平稳降级…

zotero word联动 如何使用Zotero在Word中插入参考文献

下载https://gitee.com/redleafnew00/Chinese-STD-GB-T-7714-related-csl里面论文要求的格式&#xff0c;或者word里面点这个再搜 输入好以后一定要输入空格&#xff01;