HIT-SC-Chapter Four

HIT-SC-Chapter Four

Data Type and Type Checking 数据类型与类型检验

1 Data type in programming languages

(1)Types and Variables for general computer language

通用计算机语言的类型和变量

  • 数据类型:

    • 一组值
    • 一组操作
  • 变量

    • 存储一种特定类型值的某个位置的命名
    • Example: String foo
    • 用特定数据类型定义,可存储满足类型约束的值

(2) Types in Java

  • 基本数据类型
    • int
    • long
    • boolean
    • double
    • char
  • 对象数据类型
    • String
    • BigInteger
  • 基本数据类型小写,对象数据类型大写
  • image-20220608193217426

(3) Object Types

  • 层次结构:
    • 根是Object(所有非基本数据类型都是对象类型)
    • 除Object外的所有类都有一个父类,用extends子句指定
      • 单亲继承
      • 如果省略extends子句,默认为Object
    • 一个类是它所有超类的一个实例--继承关系
      • 从其超类继承可见字段和方法
      • 可以重写方法以更改其行为 Override
  • Boxed primitives
    • 将基本类型包装成对象类型
    • 例如:
      • Boolean\Integer\Short\Long\Character\Float\Doubble
    • 通常是在定义集合类型时使用
    • 一般情况下,尽量避免使用
    • 一般可以自动转换

(4) Operators

  • 执行简单计算的符号
  • = + - * /
  • 遵循标准的数学规则
  • 字符串连接(+)

(5) Operations

  • 接受输入并产生输出的函数(有时本身也会更改值)
    • 作为前缀、中缀和后缀操作符
    • 作为对象的方法。
    • 作为一个类函数。例如:Math.sin()
      • 在这里,Math不是一个对象。它是包含sin的类。
  • Overloading operators/operations 重载
    • 同样的操作名用不同的数据类型
    • 在Java中,算术操作符+、-、*、/被大量重载于数字基本类型。
    • 方法也可以重载。大多数编程语言都有一定程度的重载。
    • (将在3.3节OOP中讨论)

2 Static vs. dynamic data type checking

  • 类型转换
  • image-20220608194753741
    • 被赋予了不合法的数据类型
    • 范围大的可以赋予范围小的
    • 范围小的不能赋予范围大的

(1) Static Typing vs. Dynamic Typing

静态类型与动态类型

  • Java是一种静态类型的语言。
  • 所有变量的类型都是在编译时(在程序运行之前)知道的,因此编译器也可以推断出所有表达式的类型。
  • 如果a和b被声明为int类型,那么编译器会得出a+b也是int类型的结论。
  • 实际上,Eclipse环境会在您编写代码时执行此操作,因此您可以在输入时发现许多错误。(静态检查)
  • 在编译时进行类型检查
  • 在像Python这样的动态类型语言中,这种检查被延迟到运行时(当程序运行时)。

(2) Static Checking and Dynamic Checking

  • three kinds
    • Static checking: the bug is found automatically before the program even
      runs.
    • Dynamic checking: the bug is found automatically when the code is
      executed.
    • No checking: the language doesn’t help you find the error at all. You have
      to watch for it yourself, or end up with wrong answers.
    • image-20220608195406425

(3) Static checking

  • Mismatched Types
    • ( 赋值语句的左右必须类型完 全一致!)
    • image-20220608195519737
  • 静态检查意味着在编译时检查bugs。
    • 静态类型检查:可在编译阶段发现错误,避免了将错误带入到运行阶段,可提高程序正
      确性/健壮性。
  • 检查错误
    • 将操作应用于错误类型的参数所导致的错误
    • 语法错误
      • 比如额外的标点符号或虚假的单词。即使像Python这样的动态类型语言也会进
        行这种静态检查。
    • 类名/函数名错误
      • like Math.sine(2)
    • 参数数目错误
    • 参数类型错误
    • 返回值类型错误

(4) Dynamic checking

  • 非法的参数值
    • 例如,只有当y实际上为零时,整数表达式x/y才会出错;否则它的工作原理。在这个表达式中,除以零不是静态误差,而是动态误差。
  • 非法返回值
  • 越界
  • 空指针

(5) Static vs. Dynamic Checking

  • 静态检查往往是关于与变量的特定值无关的类型和错误
    • 静态类型保证一个变量将具有该集合中的某些值,但直到运行时我们才确切知道它具有哪个值。
    • ?
    • 因此,如果错误只会由某些值引起,比如除以零或超出范围,那么编译器将不会引发关于它的静态错误。
  • 相反,动态检查往往是关于由特定值引起的错误。
  • 关于“类型”的检查《--》关于值的检查

3 Mutability and Immutability

(1) 赋值

  • 在计算机中,赋值是最难得问题之一,它相当于将一个计算结果放到一个存储空间中,是一个存储的过程。

    • String foo;
      foo = "JSX LOVE JJY"
      
  • 赋值可以与变量声明结合使用

    • double badPi = 3.14; 
      boolean isJanuary = true;
      

(2) Changing a variable or its value

改变一个变量、改变一个变量的值,有何区别

  • 改变一个变量:将该变量指向另一个值的存储空间。
  • 改变一个变量的值:将该变量当前指向的值的存储空间写入一个新的值。

(3) Immutability 不变性

  • 不变性:重要设计原则

  • 不变数据类型

    • 类型的值一旦创建就永远不能更改。
  • 引用类型的不变:一旦确定其指向的对象,就不能再被改变

    • 要使引用不可变,请使用关键字final声明它
    • image-20220608203826091
    • 如果编译器无法确定final变量不会改变,就提示错误---静态类型检查
    • 使用final变量尽量作为方法的输入参数和局部变量
    • Note:
      • final类无法派生子类
      • final变量无法改变值/引用
      • final方法无法被子类重写
  • 对象的不变性:

    • 对象是不可变的:一旦创建,它们总是指向同一个值/引用。
    • 可变对象:拥有方法可以修改自己的值/引用
  • String

  • StringBuilder

  • 千万不要用Date !

    • 使用java包中的一个类。time: LocalDateTime, Instant等。
    • 所有这些都在它们的规范中保证它们是不可变的
  • the risk

    • 别名是使可变类型有风险的原因
      • 安全地使用可变类型:局部变量,不涉及共享;只有一个引用
      • 多个引用,就变得不安全
  • How to Modify the code?

    • 要返回对象的新副本(防御复制)–防御性拷贝
      • 大量内存浪费
    • 如果我们使用不可变类型,那么程序的不同部分可以安全地共享内存中的相同值,因此复制更少,所需的内存空间也更少。
    • image-20220608205932223
    • image-20220608205941900

4 Snapshot diagram as a code-level, run-time, and

moment view

  • image-20220608210103889

(1) Snapshot diagrams

  • 为了理解微妙的问题,画出运行时发生的事情的图对我们来说是很有用的。

  • 用于描述程序运行时的内部状态

(2) 快照图中的基本类型和对象类型

  • Primitive values 由裸常量表示。传入的箭头是对变量或对象字段值的引用。

    • image-20220608210249634
  • Object values是由其类型标记的圆。

    • 当我们想要显示更多的细节时,我们将字段名写入其中,并用箭头指出它们的值。更详细的信息是,字段可以包含它们声明的类型。
    • image-20220608210325541

(3) Reassignment and immutable values

  • 不可变对象(设计者希望它们总是表示相同的值)在快照图中用双线椭圆表示,就像我们图中的String对象一样。
  • image-20220608210544874

(4) Mutable values

image-20220608210613695

(5) 不可变的引用

  • 在快照图中,不可重新分配的引用(final)由双箭头表示。
  • image-20220608210720048
  • 引用是不可变的,但值是可变的
  • 可变的引用也可指向不可变的值

5 Complex data types: Arrays and Collections

(1)Arrays

  • 数组是另一种类型t的固定长度序列
  • 包含所有可能的数组值,但特定的数组值一旦创建,就永远不能改变其长度。
  • 操作
    • indexing:
    • assignment:
    • length: a.length

(2)List

  • 列表是另一种类型T的变长序列。
  • 操作:
    • list.get
    • list.set(2,0)
    • list.size()
  • List is an interface.
  • members in a List must be an object.
  • Please use List rather than arrays

(3) Set

  • Set是零个或多个唯一对象的无序集合。
  • 一个对象不能多次出现在集合中。
  • 操作:
    • s1.contain()
    • s1.containAll()
    • s1.removeAll()
  • Set是一个抽象接口
  • image-20220608212511127

(4) Map

  • A Map is similar to a dictionary (key-value) 类似字典:键-值
  • Map is an abstract interface 抽象接口
    • map.put()
    • map.get()
    • map.containsKey()
    • map.remove()
  • image-20220608212606188

  • 声明List、Set和Map变量
    • 使用Java集合,我们可以限制集合中包含的对象的类型。
    • 添加项时,编译器可以执行静态检查,以确保只添加适当类型的项
    • 然后,当我们取出一个项时,就可以保证它的类型是我们所期望的。
    • 只能是引用类型:不能创建基本类型的集合
  • 创建List、Set和Map变量
    • 抽象接口needs Concrete Class The implementation
    • 它们定义了这些各自的类型如何工作,但它们不提供实现代码。
    • List: ArrayList and LinkedList
    • Set: HashSet
    • Map: HashMap
  • 使用List, Set和Map变量

(3) 迭代器

image-20220608212327790

  • image-20220608213111738

  • 迭代器是一个逐步遍历元素集合并逐个返回元素的对象。

  • 在Java中,当你使用for(…:)循环遍历List或数组

    • iterator.next()
    • iterator.hasNext()
  • 突变破坏迭代器

    • image-20220608213357594

    • image-20220608213651907

    • image-20220608213700711

    • for不能删除


6 Useful immutable types

  • 基本类型和封装对象类型都是不可变的
    • 如果需要使用较大的数字进行计算,BigInteger和BigDecimal是不可变的。
  • 不要使用可变的Date,根据所需的时间粒度使用适当的不可变类型。
  • Java集合类型的通常实现是可变的
    • Collections实用工具类具有获取这些可变集合的不可修改视图的方法:
      • Collections.unmodifiableList
      • Collections.unmodifiableSet
      • Collections.unmodifiableMap

(1)围绕可变数据类型的不可变包装器

  • 得到的结果是不可变的,只能看;

  • 缺点是在运行时获得了不可变性,而不是在编译时。无法据此进行静态检查。

  • 但这总比没有好,所以使用不可修改的列表、映射和集合是减少bug风险的好方法。

  • image-20220608214536005

image-20220608214633146

  • 不可修改的包装器通过拦截所有会修改集合的操作并抛出UnsupportedOperationException,从而剥夺了修改集合的能力。

  • 不可修改的包装有以下两种主要用途:

    • 使集合在构建后成为不可变的。在这种情况下,最好不要维护对后台集合的引用。这绝对保证了永恒性。
  • image-20220608214830760

  • image-20220608214917362

    SUM

    image-20220608215220319

    image-20220608215226637

    image-20220608215235275

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