数据类型与类型检验

数据类型与类型检验

对应 04-Data Type and Type Checking内容
不过度展开记录,仅作“写意”用

数据类型

type:(抽象上的)值的集合,及可以运作于这些值的一系列运算

特定数据类型定义,存储满足类型约束之值的结构空间——变量

基本数据类型(java提供)&对象数据类型(java库提供/程序员自行构造)

img

不能实现表达的统一 vs 泛型与表达统一

基本类型包装为对象类型:通常在定义集合类型时使用 一般情况下避免(一般可以自动转换)

操作: 操作符调用 方法(对对象调用) 函数(静态方法,对类调用)

同样的操作名用于不同的数据类型——>重载Overload

静态与动态检查

检查内容:数据类型与数据值的匹配性

Java——静态类型语言 在编译阶段类型检查(不同于Python 动态类型语言 在运行阶段进行类型检查)

显然有:静态类型检查>>动态类型检查>>不进行检查

  • 静态检查:在编译阶段发现错误 避免错误被运行 提高程序健壮性
    检查范围包括:
    • 语法错误(如final关键字无法确定不会改变则报错)
    • 类名/函数名错误
    • 参数数目错误与类型错误
    • 返回值类型错误
  • 动态检查:检查内容有:
    • 非法参数值(如除数为0)
    • 非法返回值(返回值无法用指定数据类型展示)
    • 越界
    • 空指针
  • 静态vs动态:静态检查只考虑编译阶段可以确定的“值”,动态检查涉及运行阶段可以确定的“值”

可变性与不可变性(重点)

赋值:在内存特定区域开辟一段空间写入特定值,将该空间与变量(引用)关联

  • 改变变量:变量指向另一个值的存储空间(Immutable)
  • 改变变量的值:存储空间不变,这个空间内写入一个新的值(mutable)

尽可能避免程序内的“变化”,减少副作用

不变性Immutability:不变数据类型的数据一旦创建,则不可改变。(关键设计原则)

  • 添加final关键字使引用immutable:如final int n = 14,则引用“n"不可再指向其他内容。
  • 对添加final关键字的mutable对象引用,对象可以改变值,但引用固定,不可再指向其他对象。
  • 如果编译器无法确定final变量不会改变,就提示错误,这也是静态类型检查的一部分
  • 尽量使用final变量作为输入参数/局部变量

final更偏向一种“固定不变”的决策,final的类不可派生子类,final的变量无法改变引用指向空间,final的方法无法被子类重写...等等。

不变/可变对象:指向的值不能/能被方法修改(由数据类型决定)

不变/可变引用:变量与内存区域的关系不能/能修改(final关键字决定)

存在多个引用时,可变/不可变出现明显差别(共用空间值变化引起问题)

img

img

img

  • 可变类型:最少化拷贝 效率高 性能好 适合协作 安全性差 容易导致漏洞(改变输入参数值 其他程序员难理解 内部数据结构对外泄露因而外部改变会引发内部变量变化 等等)

    防御式拷贝——返回新的对象:避免内部数据结构对外泄露

    安全使用可变类型 需尽量避免多个引用

  • 不可变类型:大量临时拷贝浪费内存 安全性更好 节省频繁复制的代价

快照图(会画)

描述程序运行时内部状态(存在的对象与方法及其局部变量等)

方便程序员的交流,便于刻画变量随时间的变化,解释设计思路

img

img

img

引用不可变,可能指向可变的值

引用可变,可能指向不可变的值

复杂数据类型:列表与集合

1、数组

int []a=new int [100] (列表也可以认为是数组 注意做出区分)

2、list

List list = new ArrayList()

  • 索引:list.get(2);
  • 赋值:list.set(2,0);
  • 长度:list.size()。

list是一个抽象接口

3、set

set是零个或多个唯一对象的无序集合。

  • s1.contains(e)测试集合是否包含元素。
  • s1.containsAll(s2)测试是否s1⊇s2。
  • s1.removeAll(s2)从s1中删除s2。

set是一个抽象的接口

4、map

类似于字典(键值对)

  • map.put(key,val) 添加映射键→val
  • map.get(key) 获取钥匙的价值
  • map.containsKey(key) 测试地图是否有密钥
  • map.remove(key) 删除一个映射

同为抽象接口

上述数据类型均为mutable,实例化时注意填写泛型(即<>内的内容);均可使用下标/迭代器/增强for循环(如for int x: []int)遍历;它们的成员必须为一个对象,而不能是基本数据类型。

对基本数据类型 可以包装为对象类型

5、 Iterator

mutable 迭代器

  • next() return
  • hasNext() return boolean

img

注意:迭代器遍历过程中的删除会引起迭代器指向元素下标值的整体前移,从而错过迭代器中的部分元素。

设计迭代器使用过程中的删除操作时要多加注意下标问题。

img

不可变:优势所在

  • 基本类型及其封装对象类型均是immutable
  • Java提供不可变类型包装器,但它们包装的mutable内容的immutable是在运行阶段取得的,无法进行静态检查

结束

posted @   2022113415-罗昊然  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示