Thinking in Java - 学习笔记 - (十四)类型信息

细读 Thinking in Java (一)一切都是对象 关于《Java编程思想》第二章 一切都是对象 阅读详情

Java编程思想 - 第十四章 - 类型信息

运行时类型信息(RTTI)使得你可以在程序运行时发现和使用类型信息。

它使你从只能在编译期执行面向类型的操作的禁锢中解脱了出来,并且可以使用某些非常强大的程序。
Java让我们在运行时识别对象和类的信息的方式:

  • “传统的”RTTI,假定我们在编译时已经知道了所有的类型;

  • “反射”机制,允许我们在运行时发现和使用类的信息。

为什么需要RTTI

再次考虑基类Shape,导出类Circle、Square、Triangle。

把Shape对象放入List<Shape>的数组时会向上转型。但在向上转型为Shape的时候也丢失了对象的具体类型。对于数组而言,它们只是Shape类的对象。

当从数组中取出元素时,这种窗口——实际上它将所有的事物都当作Object持有——会自动将结果转型回Shape。

这是RTTI最基本的使用形式,因为在Java中,所有的类型转换都是在运行时进行正确性检查。这也是RTTI名字的含义:在运行时,识别一个对象的类型。

在这里,RTTI类型转换并不彻底:Object被转型为Shape,而不是转型为Circle等。这是因为目前我们只知道这个List<Shape>保存的是Shape。在编译时,将由容器和Java的泛型系统来强制确保这一点;而在运行时,由类型转换操作来确保这一点。

接下来就是多态机制的事情了,Shape对象实际执行什么样的代码,是由引用所指向的具体对象Circle、Square、Triangle决定的。

使用RTTI,可以查询某个Shape引用所指向的对象的确切类型,然后选择或者剔除特例。

Class对象

要理解RTTI在Java中的工作原理,首先必须知道类型信息在运行时是如何表示的。这项工作是由称为Class对象的特殊对象完成的,它包含了与类有关的信息。

类是程序的一部分,每个类都有一个Class对象。换言之,每当编写并且编译了一个新类,就会产生一个Class对象(更恰当地说,是被保存在一个同名的.class文件中)。为了运行这个类的对象,运行这个程序的Java虚拟机(JVM)将使用被称为“类加载器”的子系统。

类加载器子系统实际上可以包含一条类加载器链,但是只有一个原生类加载器,它是JVM实现的一部分。原生类加载器加载的是所谓的可信类,包括Java API类,它们通常是从本地盘加载的。在这条链中,通常不需要添加额外的类加载器,但是如果你有特殊需要,那么有一种方式可以挂接额外的类加载器。

所有的类都是在对其第一次使用时,动态加载到JVM中的。

当程序创建第一个对类的静态成员的引用时,就会加载这个类。这个证明构造器也是类的静态方法,即使在构造器之前并没有使用static关键字。

因此,Java程序在它开始运行之前并非被完全加载,其各个部分是在必需时才加载的。

类加载器首先检查这个类的Class对象是否已经加载。如果尚未加载,默认的类加载器就会根据类名查找.class文件(例如,某个附加类加载器可能会在数据库中查找字节码)。在这个类的字节码被加载时,它们会接受验证,以确保其没有被破坏,并且不包含不良Java代码(这是Java中用于安全防范目的的措施之一)。

一旦某个类的Class对象被载入内存,它就被用来创建这个类的所有对象。

Class对象的方法

  • forName(String) 输入全限定的类名,返回Class对象的引用

  • isInterface() 是否为接口

  • getInterfaces() 取得接口

  • getSuperclass() 取得直接基类

  • getSimpleName() 取得不含包名的类名。

  • newInstance() 要含有默认构造器。


package thinkinginjava;

import java.util.Random;

class Initable {
    static final int staticFinal = 47;
    static final int staticFinal2 = ClassInitialization.rand.nextInt(1000);
    static {
        System.out.println("Initializing Initable");
    }
}

class Initable2 {
    static int staticNonFinal = 147;
    static {
        System.out.println("Initializing Initable2");
    }
}

class Initable3 {
    static int staticNonFinal = 74;
    static {
        System.out.println("Initiablizing Initable3");
    }
}

public class ClassInitialization {
    public static Random rand = new Random(47);

    public static void main(String[] args) {
        Class initable = Initable.class;
        System.out.println("After creating Initable ref");
        // 这行代码(staticFinal)不会触发初始化
        System.out.println(Initable.staticFinal);
        // 这行代码(staticFinal2)会触发初始化,因为它不是编译期常量
        System.out.println(Initable.staticFinal2);
        // 会触发初始化,因为不同时是final的
        System.out.println(Initable2.staticNonFinal);
        // 会触发初始化,因为要产生Class引用
        try {
//            System.out.println(Initable3.class.getName());
            Class initable3 = Class.forName("thinkinginjava.Initable3");
            System.out.println("After creating Initable3 ref");
            System.out.println(Initable3.staticNonFinal);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
} /* Output
After creating Initable ref
47
Initializing Initable
258
Initializing Initable2
147
Initiablizing Initable3
After creating Initable3 ref
74
*/

初始化有效地实现了尽可能的“惰性”。从对initable引用的创建中可以看到,仅使用.class语法来获得对类的引用不会引发初始化。但是,为了产生Class引用,Class.forName()立即就进行了初始化。就像在对initable3引用的创建中所看到的。

如果一个static域不是final的,那么在对它访问时,问题要求在它被读取之前,要先进行链接(为这个域分配存储空间)和初始化(初始化该存储空间),就像在对Initable2.staticNonFinal的访问中所看到的那样。

RTTI在Java中还有第三种形式,就是关键字instanceof。

instanceof与Class的等价性

instanceof和isInstance()保持了类型的概念,它指的是“你是这个类吗,或者你是这个类的派生类吗?”而如果用==比较实际的Class对象,就没有考虑继承——它或者是这个确切的类型,或者不是。

反射:运行时的类信息

RTTI和反射之间的真正的区别只在于,对RTTI来说,编译器在编译时打开和检查.class文件。而对于反射机制来说,.class文件在编译时是不可获取的,所以是在运行时打开和检查.class文件。

动态代理

代理是基本的设计模式之一。
不是很懂,还要去看设计模式的书。

空对象

不必执行额外的对null的检查。

接口与类型信息

反射可以轻易地访问private方法,甚至匿名类。

Codex 自定义模型操作指南:CLI 与桌面客户端双端实操 检查版本 codex --version # 预期输出类似:codex-cli 0.133.0-alpha.1 # 如未安装 npm install -g @openai/codex假设你要接入DeepSeek,在# 临时设置(当前终端会话有效)export DEEPSEEK_API_KEY="sk-你的 DeepSeek API Key"# 永久设置(推荐,写入 shell 配置) 阅读详情

相关推荐

TouchSocket TcpService:构建高性能Tcp服务的终极利器

/ 接收到的数据data");// 回复客户端await ((ITcpSessionClient)client).SendAsync("服务端已收到消息!");// 继续执行后续插件TouchSocket的TCPService以极简的API、强大的扩展性和卓越的性能,重新定义了.NET TCP服务的开发体验。无论是物联网平台还是金融级实时通信系统,TCPService均能提供可靠的基础设施支持。立即探索示例项目,开启你的高性能服务开发之旅!扩展阅读如何实现WebSocket服务?

若汝棋茗 的博客 1461

Thinking in java-27 Runtime Type Identification运行时类型确定

1. RTTI这里有关于RTTI详细的pdf文件。 RTTI lets you find the exact type of an object when you only have a reference to the base type. RTTI is used to reveal the true types at run time. 运行时类型鉴定RTTI能使得在运行时确定对象的确

toseektruth的博客 271

长期换衣行人重识别(Long-Term Clothes-Changing Person Reid)数据集汇总

长期换衣行人重识别任务中目前常用的数据集总览目前换衣数据集的主要问题数据集换衣/总体情况集统计DeepChange(2021)LaST(2021)COCAS(2020)VC-Clothes(2020)LTCC(2020)PRCC(2019)Celebrities-reID(2019) 总览 在长期换衣行人重识别的任务当中,数据集的获取(尤其是对于学术环境下)是一个难点,主要的困难有以下几点: 采集大规模的数据集比较困难。 采集不同的衣服的数据集比较困难。 采集不同衣服不同角度的数据集比较困难。 目前也有

KingsMan666的博客 8381

Thinking in java学习笔记12:第十四章(类型信息)、第十五章(泛型)

第十四章-类型信息 运行时类型信息使得可以再运行时发现和使用类型信息。 这里书中写了RTTI,RTTI是什么?这其实是作者的一个误会,RTTI是C++里面的RTTI(Run-time Type Identification),运行时获取类型信息。而java中更适合的表示是反射,可以这么说,java的反射是C发展到java后的结果。 对于反射我其实已经有笔记了,而且我对这张内容表示有...

沙丁鱼的博客 207

评价模型——层次分析法(AHP)与熵权法(EWM)

层次分析法是定性与定量结合的多准则决策、评价方法。将决策的有关元素分解成目标层、准则层和方案层,并通过人们的判断对决策方案的优劣进行排序,在此基础上进行定性和定量分析。它把人的思维过程层次化、数量化,并用数学为分析、决策、评价、预报和控制提供定量的依据。

好好学习 天天向上 2万+

GOM Correlate拉伸试验后处理操作

本文描述了使用GOM Software 2022对拉伸试样进行后处理的操作,包括设置检测点、引伸计、输出应变数据到表格、输出报告为视频等

qq_45008924的博客 4665

Thinking in Java第十四章学习笔记----类型信息

* 转载于:https://www.cnblogs.com/promiseslc/p/8996002.html

weixin_30546189的博客 146

精密加工零件自动报价智能体设计与实现

摘要 本文设计并实现了一个精密加工零件自动报价智能体系统。该系统通过计算机视觉和几何分析技术,自动读取3D图纸(STEP/STL格式),提取影响加工成本的几何特征,实现精准报价。系统采用模块化设计,包含3D模型解析、特征提取、成本计算和报价生成四个核心模块。关键技术包括:使用PythonOCC处理STEP文件,Trimesh处理STL网格;实现体积、表面积、包围盒等基础几何量计算;开发特征提取算法识别复杂曲面、深孔等加工难点;基于规则库进行可加工性评分和成本估算。相比传统人工报价方式,该系统能显著提高报价效

AI的内部世界的博客 112

thinking in java 14章 类型信息 学习笔记

1.我们需要类型信息有什么用? 类型转换时检查是否可行,在java中所有的类型转换都是在运行时进行正确性检查的。这里就必须用到类型信息。在继承体系中有时候需要知道基类对象引用所指向的对象的具体类型,以做一些具体的操作。 2.类型信息在运行时是如何表示的? Class对象,它包含了与类有关的信息。类型检查实际上用到了这个对象(说法来自java编程思想)每当编写并编译了一个新类就

yinjd的专栏 777

Uniapp微信小程序:详解根据角色权限动态展示底部tabbar,支持不同身份显示不同底部导航+灵活权限组合完整源码,菜单切换不闪烁、秒加载不卡(提供动态原生Tabbar配置+自定义组件形式2种方案)

uni-app微信小程序实现根据用户不同角色显示不同的tabBar,uniapp微信小程序原生tabbar实现动态菜单导航,微信小程序动态tabBar实现:基于自定义组件,灵活支持不同用户角色,动态pages,uni-app微信小程序动态tabBar,根据不同用户展示不同的tabBar,uni-app微信小程序动态切换tabBar,根据不同用户角色展示不同的tabBar,微信小程序自定义底部tabbar动态修改,Uniapp小程序根据权限(角色)不同动态展示底部tabbar,解决tabbar闪烁卡顿问题,小

✅ 精选推荐文章 4284

部署OpenClaw(ClawdBot、MoltBot)后访问localhost:18789报1008错误怎么办?

部署openclaw(曾用名ClawdBot、MoltBot)后访问localhost:18789出现1008授权错误❌?本文分享如何快速解决这个问题✅

XiaoqiangClub的博客 1万+

Thinking in Java 整理笔记:类型信息

本章将讨论Java是如何让我们在运行时识别对象和类的信息的: 一种是“传统的”RTTI,他假定我们在编译时已经知道了所有的类型;另一种是“反射”机制,它允许我们在运行时发现和实用类的信息。 PS:“运行时类型识别”(RTTI). 1.RTTI:类型信息在运行时是如何表示的?这项工作是由成为Class对象的特殊对象完成的,它包含了与类有关的信息。 2.事实上,Class对象就

zhangqix的专栏 740

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Thinking in Java

Thinking in Java (Java编程思想) 学习总结心得(一) 前序: 学习java也已经有大约两年时间,但大多数断断续续,零散没有系统学习。这次经多方推荐购买了一本java学习必读书籍《Thinking in Java》学习之余将书中的心得和书中的重点内容总结写于此。 第一章 对象导论 我们之所以将自然界分解,组成各种概念,并按其含义分类,主要是因为我们是整个口语交流社...

周日王的博客 1306

Devexpress16.2.6破解工具

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

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Thinking in java目录概述

文章目录目的整书概况总结 目的 为什么要选取《Thinking in java》这本书? 语言本身:Java程序语言在实际场景开发中有非常多的通途,许多互联网产品的basic依托于java语言来实现 书籍:我始终认为思想性的东西是最重要的,可以为自己的行为划定标准,知道什么样的思考方向是合理的,基本的思考框架应该是什么 阅读书籍首先应该对整本书有一个初略的了解和认识。 整书概况 通过阅读目录大...

在黑夜中前行 1349

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

《Thinking in java》-学习笔记(9)

第9章 违例差错控制 1.基本违例 方法是创建一个特殊的对象,代表我们的信息,将其掷出我们当前的场景之外, 产生一个违例: if(t == null) throw new NullPointerException(); 这里用new在内存堆里创建违例,并需要调用一个构建器。标准的违例中,有两 个构建器,一个是默认构建器,另一个是需要使用一个字串自变量。 if(t == null)...

DeepingC 762

《Thinking in java》-学习笔记(8)

第8章 对象的容纳 1.数组 考虑到执行效率和类型检查,尽可能地采用数组。 2.集合 四种类型:Vector(矢量)、bitset(位集)、Stack(堆栈)、Hashtable(散列表)。 Hashtable是一种关联数组,允许我们将对象关联起来,集合类会自动改变自身的大小。 缺点是:将对象置入一个集合时丢失了类型信息,在使用的时候必须进行造型。 3.枚举器(反复器) 可以利用集...

DeepingC 1459

Thinking in Java 源码的获取以及编译问题

《Java编程思想》的源代码的获取、编译过程,以及编译中碰到的错误。还有Ant程序的获取和配置。

pdcxs007的专栏 5272

《Thinking In Java》 VS 《Effective Java》 VS 《深入理解Java虚拟机》

今天刚考完试,在5天以前的前4个月时间里,我很庆幸自己选了一个看书的学习途径。从上个学期的暑假到现学期的11周里面,读了《Thinking In Java》、《深入理解Java虚拟机》和《Effective Java》,感悟颇多。首先先说明一下,我以前是看视频学习的,就做过两三个学校的网站,都已经上线在使用。没做过什么特别高大上的东西,所以我是处在新手的角度去读书的,我也知道自己的理解很浅,不

小浩子的博客 2万+

Thinking in java: 14类型信息

1.  java识别对象和类的信息的两种方式:   (1)RTTI,她假定我们在编译时已经知道了所有类型;名字含义:在运行时,识别一个对象的类型。   (2)反射机制,他允许我们运行时发现和使用类的信息。2. 类是程序的一部分,每个类都有一个Class对象。换言之,每当编写并且编译了一个新类,就会产生一个Class对象(更恰当的说是被保存在一个同名的.class文件中)。为了生成这个类的对象,ja...

oYeYuanXinZhiZhu1的专栏 290

thinking in java学习记录(十四)类型信息

14.1 为什么需要RTTI 14.2 Class对象 14.2.1 类字面常量 14.2.2 泛化的Class引用 14.2.3 新的转型语法 14.3 类型转换前先做检查 14.3.1 使用类字面常量 14.3.2 动态的instanceof 14.3.3 递归计数 14.4 注册工厂 14.5 instanceof与Class的等价性 反射:运行时的类信息 ...

c630843901的博客 174

Thinking In Java——类型信息读书笔记及摘录

运行时类型信息使得你可以在程序运行时发现和使用类型信息。 在Java中主要有两种方法让我们在运行时识别对象和类的信息:第一种是“传统的”RTTI,它假定我们在编译时已经知道了所有的类型;另一种是“反射”机制,它允许我们在运行时发现和使用类的信息。 为什么需要RTTI? 面向对象编程中基本的目的是:让代码只操纵对基类的引用。这样,如果添加一个新类来扩展程序,就不会影响到原来的代码。 示例代码: ab...

qq_40462579的博客 316

运行Thinking in Java里的codes

Thinking in Java的配套代码实操

TVXQ_xy的博客 1271

Thinking in Java 附录之推荐书籍

陈昊鹏等翻译自Thinking in Java 第三版书籍Thinking in Java, 2nd Edition。本书所附光碟里就有此书,这是一个包含了完整索引并以颜色突出语法的HTML版本。你也可以从www.BruceEckel.com 免费下载。它还包含了一些没有收录到第三版的内容;详细情况请参考书中的目录。Thinking in Java, 1st Edition。本书所附光碟里就有

sunsnowad的专栏 2154

Thinking In Java 学习笔记 14.类型信息

RTTI 运行时类型信息使得你可以在程序运行时发现和使用类型信息。多态,通过动态绑定,非让代码只操纵对基类的引用(面向对象编程的基本特性)传统的类型转换代表对象类型的Class对象关键字instanceof每个类都有一个class对象,所有类都是在对其第一次使用时,动态加载到JVM(中的类加载器)中的Class.forName("class1"),获得对class对象的引用如果已经有了一个该类型...

越努力, 272

深入Java编程:《Thinking in Java》第四版代码库推荐

深入Java编程:《Thinking in Java》第四版代码库推荐 项目介绍 《Thinking in Java》第四版是由Bruce Eckel编写的经典Java编程书籍,涵盖了Java 5/6的核心概念和技术。本书不仅提供了丰富的理论知识,还附带了大量的代码示例,帮助读者深入理解Java编程的精髓。为了方便读者学习和实践,本书的代码库已经开源,并托管在GitHub上。通过下载和安装这些代码...

gitblog_00164的博客 865

Thinking in java 习题答案

这个是我在学习thinking in java过程中所做的习题(不全),和大家分享,希望能共同进步以下是下载地址: http://211.155.234.58/coa/download.html     ----------------------------------------------------------------------------------

天堂来客 3057
上一篇: Thinking in Java - 学习笔记 - (十三)字符串
下一篇: Thinking in Java - 学习笔记 - (十五)泛型
「已注销」
博客等级 码龄10年 5粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值