HIT 软构--4 数据类型与类型检验

从本章开始,介绍本课程的重点:

  • 软件构造的理论基础——ADT
  • 软件构造的技术基础——OOP

一、编程语言中的数据类型

以本课程使用的java语言为例,数据类型是一组值,以及可以对这些值执行的操作。变量是用特定数据类型定义,可存储满足类型约束的值。java语言的数据类型分为两种,基本数据类型和对象数据类型。

其中,对象数据类型形成层次结构。比如extends(继承)关系,它允许一个类(子类)继承另一个类(父类)的属性和方法。

二、静态(Static)与动态(Dynamic)数据类型检查

所谓检查,检查的是”型“与”值“的匹配性。

java是一种静态类型语言,因此,在编译阶段就会进行类型检查,也就是说,当输入的类型与数值不匹配时,编译器就会报错。而动态类型语言,只有运行时才会报错。所以说,静态类型检查是在运行之前bug就会被检查出来的,避免了将错误带入到运行阶段。而动态则只能在运行阶段。

三、可变与不可变

“赋值”的本质:在内存特定区域开辟一段空间,写入特定值,将该空间与变量(引用)关联到一起。

那么,改变一个变量,与改变一个变量的值又什么区别呢。在java语言中,改变一个变量指的是将一个变量指向另一个存储空间,改变一个变量的值,指的是将该变量当前指向的存储空间中写入一个新的值。

String a = “abc”; a = “def”;
//改变一个变量
Date a = new Date(2024, 1, 1); a.setMonth(2);
//未改变变量,向变量中写入新值

数据类型的immutability(不变性)是十分重要的,不变数据类型一旦被创建,其值就不能再改变。比如String类型,一旦某个存储空间内部的值被定义,就永远无法改变。于是表面上看上去的”更改其值“操作,实际上是给新的值又找了一块存储空间,只是此时这个String变量指向的地址变为了这个新的存储空间。

除了值的不变性,java语言还提供了引用的不变性。被引用的变量一旦被定义为final,那么其指向的内存对象就被确定,该指向关系也不能再被改变。如果编译器无法确定final变量不会改变,就提示错误,这也是静态类型检查的一部分。

所以,尽量使用final变量作为方法的输入参数或作为局部变量。这样可以有效的规避数据暴露后被改变的风险。

总的来说,可变性与不变性能分成两个维度进行总结:

  • 不变对象:一旦被创建,其指向的值不能被修改
  • 可变对象:拥有方法可以修改其指向的值

这是数据类型本身决定的。

  • 不变引用:一旦被创建,变量和内存区域之间的关联关系无法修改
  • 可变引用:变量和内存区域之间的关联关系可以修改
这是有无final 决定的。
也就是说,对于不变的引用,其对象也可能是可变的,所以值也可能改变。对于不变的对象,其引用也可能是可变的,只需改变其内存空间的指向就可以改变其指向的值。
那么,看起来可变性与不变性的争论是没有必要的,因为不管怎么说,最后呈现出来的值似乎都是同样的被更改的数值。如果只有一个引用指向该值,结果自然一样。然而,若多个引用都指向一个值,就会有差异体现。
String是java语言中的一个值不可变类型。我们定义一个StringBuilder类,其是可变的类型。那么,就会有如下结果:
这时,s与sb的输出结果就不同了。
可变的数据类型可以减少无用的内存空间占据,可能具有更好的性能。然而,不可变数据类型更安全,在其他的方面的质量更高。利用之前章节的”折中“法,我们要在实际应用中,看目前的场景更看重哪方面的性能。
为了保证数据的安全性,我们通常使用不可变的数据类型。比如将Date改为LocalDate。另外,还有不同的防止数据暴露方式。
(1)防御式拷贝。指创建一个新的对象存储该方法中对传入参数的操作结果。但是,这样会浪费大量的内存空间。如果直接使用不可变类型则会直接避免参数被修改。
(2)局部变量。此时可以安全地使用可变类型。也就是说,对于一个变量,只给它一个引用,不要涉及共享。

四、Snapshot

用于描述程序运行时的内部状态,刻画各变量随时间变化。

基本类型值通常由箭头直接指向,一个箭头表示一个引用。

对象类型值是按其类型标记的圆。当我们想显示更多细节时,我们会在里面写字段名,箭头指向它们的值。有关更多详细信息,字段可以包括其声明的类型。

不可变对象:用双线椭圆
不可变的引用:用双线箭头

五、复杂数据类型

Interator(迭代器)

是一个可变的类型。有两个方法。

(1)next(),返回集中的下一个数。这是一个可变的方法。

(2)hasNext()测试是否遍历到集合中最后一个数。

List、Map、Set

不多赘述其用法。在java语言中,他们都是可变的。

六、实用的不可变类型

我们知道,以上三中集都是可变的。那么,如何使用不可变得它们?Collections具有用于获取这些可变集合的不可变的方法:

不可变的包装:

此外,还可以用不可变的方法使这些集不可变。比如使用List.of,Map.of,Set.of方法创建新集。

使用List.copyOf也可以得到一个可变List在当前值的情况下的一个不可变的copy。

  • 32
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
碰撞检测是指在游戏或者模拟中检测两个物体是否发生了碰撞。在网页开发中,我们可以使用JavaScript实现简单的碰撞检测。在01-object-hit-test.html中,实现了一个基于Canvas的简单碰撞检测示例,通过判断两个圆形物体之间的距离是否小于它们的半径之和来判断它们是否发生了碰撞。 具体实现步骤如下: 1. 定义两个圆形物体(对象),包括其位置、半径、颜色等属性。 ``` var circle1 = { x: 100, y: 100, r: 50, color: "#FF0000" }; var circle2 = { x: 200, y: 200, r: 80, color: "#0000FF" }; ``` 2. 在Canvas中绘制两个圆形物体。 ``` ctx.beginPath(); ctx.arc(circle1.x, circle1.y, circle1.r, 0, 2 * Math.PI); ctx.fillStyle = circle1.color; ctx.fill(); ctx.beginPath(); ctx.arc(circle2.x, circle2.y, circle2.r, 0, 2 * Math.PI); ctx.fillStyle = circle2.color; ctx.fill(); ``` 3. 计算两个圆形物体之间的距离。 ``` var distance = Math.sqrt(Math.pow(circle1.x - circle2.x, 2) + Math.pow(circle1.y - circle2.y, 2)); ``` 4. 判断两个圆形物体是否发生碰撞。 ``` if (distance < circle1.r + circle2.r) { console.log("Collision detected!"); } ``` 完整代码如下: ``` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Object Hit Test</title> </head> <body> <canvas id="canvas" width="400" height="400"></canvas> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var circle1 = { x: 100, y: 100, r: 50, color: "#FF0000" }; var circle2 = { x: 200, y: 200, r: 80, color: "#0000FF" }; ctx.beginPath(); ctx.arc(circle1.x, circle1.y, circle1.r, 0, 2 * Math.PI); ctx.fillStyle = circle1.color; ctx.fill(); ctx.beginPath(); ctx.arc(circle2.x, circle2.y, circle2.r, 0, 2 * Math.PI); ctx.fillStyle = circle2.color; ctx.fill(); var distance = Math.sqrt(Math.pow(circle1.x - circle2.x, 2) + Math.pow(circle1.y - circle2.y, 2)); if (distance < circle1.r + circle2.r) { console.log("Collision detected!"); } </script> </body> </html> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值