数据类型和类型检测

Data Type And Type Checking

1.编程语言中的数据类型

类型和变量

  • 一个类型是一系列值的集合,这些集合可以抽象出一个相同的特点,并且可以相互实现计算

    • 例如:
      • 布尔类型:true or false
      • 整形:1,2,3…
      • 浮点数类型:1.2,2.4,5.55…
      • 字符串类型:“hello”,“world”
  • 变量:一个被命名的地址,存储了某种类型的值

JAVA中变量指向的地址不一定存储的就是我们想要的值,也有可能是值的“遥控器”

Java中的数据类型

Java是一个纯粹的面向对象的编程语言,因此在Java中几乎所有变量都是一个对象,但是为了高效性,可移植性和轻便性,Java也有一些基本数据类型

  • 基本数据类型:int,double,boolean,char…
    • 基本数据类型存储在栈上
    • 每个基本数据类型都有对应的包装类
    • 包装类和基本数据类型直接可以自动装包和拆包
  • 对象数据类型:String,BigInteger,BigDecimal…
    • 对象数据类型存储在堆上
    • 定义的对象变量应该是一个引用,也就是上文说到的"遥控板"
    • 引用是存储在栈上的
    • 对象数据类型在Java中是单继承的,并且有一个最终父类:Object
    • 继承关系的层次结构如图1
      图1

虽然在栈上开辟空间存储数据以及销毁数据要快于在堆上,不过在现代结构的优化下,在堆上和栈上存储的代价几乎相同

2.动态 Vs. 静态数据类型检测

类型转换

int a = 2;
double a = 2;
int a = (int)18.7
double a = (double)2/3;int a = 18.7;
String a = 1;

结果:以上代码中1-4显示编译通过,6-7编译错误

向大的类型中存储小的值,会发生自动类型转换,不会发生问题;但是向小的类型中存储大的值,就会发生精度丢失,因此会报错,需要显示的指定,是否要丢失这部分精度

静态检测和动态检测

  • 静态检测:在代码运行之前发现bug
  • 动态检测:在代码运行时发现bug
  • 无检测:语言不帮助你检测,自己找bug

三种检测方式的效率:静态>>动态>>无检查

静态检测

在编译阶段发现错误,避免将错误带入到运行阶段,可提高程序正确性与健壮性

运行阶段发现bug会带来更多的时间代价

检测内容:

  • 语法错误,例如:多了一个逗号或奇怪的单词
  • 类名/方法名错误,例如:Math.abd(-1)
  • 参数数目错误,例如:Math.abs(20, -10)
  • 参数类型错误,例如:Math.abs("hello")
  • 返回类型错误,实际的返回类型和方法要求的不能隐式转换
动态检测

在运行阶段发现错误

检测内容:

  • 非法的参数值,实参类型不能隐式转换为形参类型
  • 非法的返回值,返回类型和变量类型不能隐式转换
  • 越界:遍历数组、集合的时候索引超出了它们的容量
  • 空指针:对象的引用指向null

动态与静态的区别:静态检查只考虑编译阶段能确定的“值”;动态检查关心运行阶段能确定的“值”

3.可变性与不可变性

什么是赋值?

赋值是指,在内存空间中开辟一个空间,写入特定值,并且把变量和这块空间相关联

基本数据类型 Vs. 对象数据类型

  • 基本数据类型:在栈上开辟空间,只与栈相关联
  • 对象数据类型:在栈上开辟空间存储引用,在堆上开辟空间存储对象

引用就像一个遥控板,而对象则是电视机,可以在任何地方使用遥控板控制电视机,而不需要背着电视到处移动

变与不变

int a = 10;
a = 20;String s = "hello";
s = "world";

改变的方式有两种:改变变量和改变值

  • 改变变量:改变变量的指向,让它指向另一块空间
  • 改变值:改变变量指向的内存空间中的值,而不改变其指向

在编程中应该更多的使用immutable的数据,这样能大大提高程序的安全性

什么时候是哪种改变?
  • 改变值:基本数据类型都是改变值,可变对象数据类型访问其堆上的空间改变其中的值
  • 改变变量:对象数据类型改变其引用的值

还可以使用final关键字修饰变量,被修饰的变量其本身不可变。

对于基本数据类型,其本身就是值,因此值不可变

对于对象数据类型,其本身实际上是"遥控板"即引用,因此引用本身不可变

不变对象 Vs. 可变对象
  • 不变对象:引用指向的值不可变
  • 可变对象:拥有方法可以修改堆上数据

String类型就是一个不可变类型,不能对字符串本身进行增删的操作

StringBuilder则是一个可变类型,可以对其指向的数据进行增加删除的操作

可变类型的优势
  1. 可变类型可以最少化拷贝以提高效率
  2. 可以获得更好的性能
  3. 适用于多个模块之间共享数据
不可变类型的优势
  • 不可变类型更"安全"

4. 防御式拷贝

  • 试想以下场景:向一个方法中传入一个可变对象,这是一件相当危险的事。不同于基本数据类型和不可变数据类型,传入一个可变对象,相当于把堆上数据的权柄全部交给了这个方法,客户端的数据可以随意被远端程序员更改,虽然社会是充满真善美的,但是我们还是喜欢由自己掌握自己的命运。

  • 再试想以下场景:我重生成为了一个后端程序员,每天勤勤恳恳写代码,有一天我一如既往的打开电脑准备开启码代码的一天,发现我的数据被改了,在小小的电脑里挖呀挖呀挖,焦头烂额找不出错误,最后把代码发给了gpt,少不了一番自嘲。原来是你的一个方法里,向客户端返回了一个可变对象,客户端拿着这个对象到处霍霍,把值给霍霍乱了。

以上两个场景都是可变对象可能带来的安全隐患,贸然将数据权柄交给它人是一件相当莽撞的事情。为了解决这个问题,最好的方式就是使用不可变对象。还有一种方式就是采用所谓的防御式拷贝,简单来说就是创建一个新的可变类型对象,并且把原始对象的数据拷贝到新的堆内存上,然后将新的对象返回或传入。

  • 大部分时候这个拷贝不会被客户端修改,可能造成大量的内存浪费
  • 直接使用不可变对象,节省了频繁拷贝的代价
  • 使用可变类型最好的方法:一个堆内存只有与一个引用相关联。

5.复杂数据类型:数组和集合

数组

  • 数组是一个连续的组,其中存储相同数据类型的变量

  • Java中数组和c++中的不一样,Java中数组的数据也存储在堆上

  • 数组名也是一个引用

  • 数组中的元素通过索引访问

集合

List

List和数组很像,不同的是List的容量可以变化

List还可以对对其中的数据进行增删查改

Set

无索引,无法通过索引访问元素

Set集合中不存在相同值的元素

Map

Map中存放的是一对又一对的键值对,通过key寻找value

Map中的元素也不能通过索引访问

Map中只能每个键值只能存在一个

迭代器

迭代器是一个可以逐步遍历结合的对象

通过迭代器不能改变集合中对象的值

如果集合发生了增加或删除元素,那么之前的迭代器会失效

6.总结

  • 类型检查
    • 类型检查可以帮助提升程序的健壮性,可以帮助找出程序的错误
    • 类型检查是简单易懂的
    • 类型检查帮助你更好的维护代码
  • 可变性与不可变性
    • 可变数据具有高效性
    • 不可变数据具有安全性
    • 如何在效率和安全中选择一个合适的尺度,需要通过具体的要求进行分析
    • 关键的设计准则在于,使用尽量多的不可变对象和不可变引用

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JUC:double-checked locking(DCL) 懒汉单例模式

文章目录 double-checked locking(DCL) 问题解决方法 volatile作用 double-checked locking(DCL) 问题 第一个if用于后续进入的线程,不用再获取锁来判断是否已经创建了对象。第二个if,为的是第一个进入的线程创建对象,以及防止卡在第一个if之…

提升你的CSS技能:深入理解伪类选择器和伪元素选择器!

在CSS的世界里,有些选择器并不像它们的名字那样直接。今天,我们要探索的是两种特殊的选择器:伪类选择器和伪元素选择器。它们虽然名字相似,但功能和用途却大有不同。 下面就让我们一起来了解一下它们是如何在我们的页面布局中扮演…

GoogleNet神经网络介绍

一、简介 GoogleNet,也称为GoogLeNet,是谷歌工程师设计的一种深度神经网络结构,它在2014年的ImageNet图像识别挑战赛中取得了冠军。该神经网络的设计特点主要体现在其深度和宽度上,通过引入名为Inception的核心子网络结构&#x…

vue项目视频播放ckplayer使用

ckplayer 官方网址,点击访问 1,打开网页后能看到这里,我现在使用的是最新 X3版手册 2,这个ckplayer不是npm 插件,要下载安装包解压到项目里面使用 安装包网址 通过gitee下载 3,解析安装包到项目中 publ…

护眼台灯哪个牌子最好,护眼台灯五大品牌墙裂分享

近视在儿童中愈发普遍,许多家长开始认识到,除了学业成绩之外,孩子的视力健康同样重要。毕竟,学业的落后可以逐渐弥补,而一旦孩子近视,眼镜便可能成为长期伴随。因此,专业的护眼台灯对于每个家庭…

【zlm】音视频流与音频流合并的设计

目录 设想一 设想二 方案三 关键技术 测试语句 测试脚本 参考文档 设想一 //开始录制_option.mp4_save_path custom_path;_option.mp4_max_second max_second;vector<Track::Ptr> mytracks getTracks();auto src MediaSource::find( DEFAULT_VHOST, "1&quo…

今天起,ChatGPT无需注册就能用了!

就在刚刚&#xff0c;OpenAI狠狠地open了一把&#xff1a; 从今天起&#xff0c;ChatGPT打开即用&#xff0c;无需再注册帐号和登录了&#xff01; 像这样&#xff0c;直接登录网站&#xff0c;然后就可以开启对话&#xff1a; OpenAI对发布这个“超自由版ChatGPT”的解释是&am…

将 EDI 从 VAN 迁移到知行之桥:EDI 成本降低 90%

G公司帮助零售商在网上和实体店取得成功&#xff0c;是来自300家顶级制造商网络中包含狩猎&#xff0c;钓鱼&#xff0c;露营和体育用品等45,000 多种商品的批发分销商。 通过可靠的客户服务、良好的定价和超越标准大卖场产品的库存量&#xff0c;G公司的重点是为零售商、电子…

JavaScript邂逅

文章目录 Javascript内容邂逅JavaScript前端的三大核心计算机语言认识编程语言常见的编程语言编程语言的发展历史–机器语言阶段一: 机器语言 编程语言的发展历史–汇编语言阶段二:汇编语言 汇编语言的发展历史–高级语言阶段三:高级语言 机器语言和高级语言 认识JavaScriptJav…

Vmware虚拟机远程SSH连接失效解决方法及分析过程

问题描述 系统为CentOS7 64位 一向能够正常连接 在某次使用FinalShell进行远程SSH连接时 突然无法连接 对问题原因猜测及尝试 1.dns解析失效 发现显示DNS无法解析,可以得知是使用了主机名登录,而主机名无法登录. 遂查看host文件.host文件因不知名原因被清空,重新恢复后该问…

初识编译和链接(C语言)

文章目录 编译和链接翻译环境预处理编译汇编链接 运行环境 编译和链接 编译和链接这两个大的过程构成了翻译环境。 其实&#xff0c;在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境。 一个环境是翻译环境&#xff0c;另一个是执行环境。 翻译环境中&#xff0c;源…

STM32之HAL开发——不同系列SPI功能对比(附STM32Cube配置)

不同系列STM32——SPI框图 F1系列框图 F4系列框图 TI模式时序图特性 F7系列框图 H7系列框图 注意&#xff1a;F7系列以及H7系列支持Quad-SPI模式&#xff0c;可以连接单&#xff0c;双或者四条数据线的Flash存储介质。 SPI——Cube配置流程 RCC时钟源配置 SYS系统调试模式配…