软件构造学习心得之数据类型与类型校验

目录

1 数据类型

2 静态与动态类型检查(Static/dynamic data type checking)

2.1 静态检查

2.2 动态检查

3 可变与不可变数据类型(Mutability/Immutability)

3.1 改变变量

3.2 改变值

3.3 不可变类型

3.4 防御性拷贝(Defensive Copying)

4 代码快照

5 知识框图


1 数据类型

在Java中,主要包括两种数据类型:基本数据类型(primitive types)和对象数据类型(object types)。

  • 基本数据类型:包括int,long,byte,char,float,double,boolean。这些类型的数据,只有值,没有标识id,并且为immutable类型。
  • 对象数据类型:包括Class ,interfaces ,arrays ,enums ,annotations。这些类型的数据,有值,并且有标识id,其中部分为mutable类型。

为了更清楚的阐述这两种类型,结合 个人理解 做出一些解释:为什么说基本数据类型是可变的,且无id的?如果我们申请一个int型变量a,赋予初值为7。再申请一个int型变量b,赋予初值也为7。Java在处理时,a申请时,java在栈中搜索是否有内存存储了整型的7,如果没有,便申请一块内存来存储整型7。在处理b的声明时,发现存在整型7,则直接将b指向对应内存的位置。因此,a和b实际上指向同一块内存。但是又因为int型是immutable的,因此,改变a的值,使得a=6,实际上是让a指向了内存存储整型6的地方(如果没有则申请一块新的位置),并不是修改原内存空间的值。b仍然指向之前的地址,而a指向了一块新的地址。这种行为实际上和immutable的对象数据类型很相似。我认为,不管是对象数据类型和基本数据类型,变量名称都与C语言的指针相似。

在容器类中,要求存储的元素必须为Object,因此,当我们想在容器类中存储基本数据类型时,就需要对其进行转化,将其转化为对象数据类型,即:Boolean, Integer, Short, Long, Character, Float, Double型,这些与Object相同,有id,且为immutable类型。Java有时候会自动的进行转换。如:

List<Integer> list = new ArrayList<>();
list.add(1);

Java会自动将1转化为Integer型。

2 静态与动态类型检查(Static/dynamic data type checking)

2.1 静态检查

Java是一种静态类型语言,即:所有变量的类型在编译时已知,因此编译器可以推导表达式类型。显然,在Java中申请变量时,都需要对变量的类型进行声明,这与Python这种动态语言大不相同。静态检查是在编译阶段进行的类型检查。主要包括:

  1. 语法错误Syntax errors
  2. 函数名错误Wrong names
  3. 参数错误Wrong number of arguments
  4. 参数类型错误Wrong argument types 
  5. 返回值类型错误Wrong return types

从静态检查的主要内容中可以看出,静态检查主要考察考虑特点类型,名称,不考虑特定值。

2.2 动态检查

Java虽然不是一种动态类型语言,但是同样会进行动态类型检查。动态类型检查主要包括:

  1. 非法的参数值Illegal arguments values
  2. 非法的返回值Unrepresentable return values
  3. 越界Out-of-range indexes
  4. 空指针Calling a method on a null object reference

其中非法是指数值不合法,如除以0等等。动态类型检查是考虑程序在运行中特定值引起的问题。这种由特定值引起的错误无法被静态检查发现(编译器不能确定在程序运行的过程中,这些变量的取值)。

3 可变与不可变数据类型(Mutability/Immutability)

3.1 改变变量

改变一个变量,是指改变变量所指向的存储空间,类比于C语言,可以理解为等于改变指针指向。

3.2 改变值

改变一个变量的值:是指改变该变量当前指向空间的值,类比于C语言,相当于改变指针指向空间的内容。

3.3 不可变类型

对于非引用类型,不可变类型:一旦创建值不能再被改变
对于引用类型,不可变类型:一旦确定指向对象,不能再改变指向其他对象
方法:使用关键词final修饰
注意:

  • fina l类  无法派生子类
  • final 变量  无法改变引用
  • final 方法  无法被子类重写

例如:String就是一个Immutable的对象,给String增加字符时,实际上是创建了一个新的String,并修改原String指向新生成的String

图1 String是不可变类型

 

编译器进行静态类型检查时,如判断final变量首次赋值后发生了改 变,就会提示错误。

3.4 防御性拷贝(Defensive Copying)

 对于可变类型,因为其值可以被改变,因此在方法中通常需要进行防御性拷贝,防止信息泄露,导致在外部修改内部属性。主要包括:

  • 构造函数时进行防御性拷贝
  • 返回值时进行防御性拷贝

前者是为了防止在传入时,外部修改导致内部变化。后者是为了防止client修改导致内部改变以及内部修改导致client出现错误。

4 代码快照

基本类型:

可变引用的(无final修饰):

图2 基本类型-可变引用

不可变引用的(有final修饰):

 图3 基本类型-不可变引用

对象类型:

可变引用的(无final修饰),Mutable:

图4 Object-non final-Mutable

可变引用的(无final修饰),Immutable:

图5 Object-non final-Immutable

 

不可变引用的(final修饰),Mutable:

 

图6 Object-final-Mutable

不可变引用的(final修饰),Immutable:

图7 Object-final-Immutable

5 知识框图

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值