栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

软构复习4数据类型与类型检验

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

软构复习4数据类型与类型检验

一、数据类型

数据类型:一些值的集合,以及在值上的操作

Java中的5种原始类型:int,boolean,double,long,char

对象类型:String,BigInteger

java中基本数据类型是小写,而对象数据类型是首字母大写

变量:用特定数据类型定义,并且存储满足类型约束的值

java中两种数据类型的比较:

除了object是祖先类以外,其他类都是继承了某一个类,继承形成了层次结构

子类从超类中继承可见的方法和成员,且可以重写超类方法

包裹类型:Boolean,Integer,Double,Short,Character,Float

通常在定义集合类型的时候使用它们,一般情况下尽量避免使用

包裹类型可以向下兼容它们的基本类型

重载(Overload):方法具有相同的名称,而参数列表(个数/类型)不相同,重载对返回类型是否相同不做要求

二、动态类型检查与静态类型检查:
java是静态类型语言:在编译阶段进行类型检查

动态类型语言:在运行阶段进行类型检查

一种语言提供的检查类型:静态,动态,无检查

静态>动态>无检查

Java验证类型是否始终匹配

静态类型检查在编译阶段发现错误,避免将错误带到运行阶段,提高了程序的健壮性和正确性

静态类型检查:

语法错误,函数名错误,参数类型错误,参数个数错误,返回值类型错误

动态类型检查:
非法的参数值:如整数x/y,只有在y实际为0时才会错误

非法的返回值:最后得到的返回值无法用声明类型表示,越界,空指针

静态类型往往是检查类型的,而动态类型检查检查特定值,一个错误由特定值触发,那编译阶段不会报错

int big = 200000 ;  big = big * big ; 无报错,但是会出现错误的结果 double sum = 7 ; double n = 0 ; double average = sum / n ; 不报错,结果为无穷 int sum = 0; int n = 0; int average = sum/n;

动态类型错误

三、可变性与不变性:
赋值:用“=”,可以和变量声明结合在一起:double a=2.0

改变一个变量:将它指向另一个值的存储空间

改变一个变量的值:向它当前所指的值的存储空间中写入另一个值

程序不能没有变化,但是要尽量避免变化以避免副作用

不变数据类型:一旦被创建,值不能被改变 例如:String是,包裹类型是,List不是

在任何变量前面加final也可以使其成为不可变引用

final int a=5;(不能再被赋值了)

编译器会检查final修饰的变量值是否改变

尽量使用final变量作为方法的参数

注意:final类无法派生子类;final变量无法改变值/引用;final方法无法被子类重写

不变对象:一旦被创建,始终指向同一个值/引用 可变对象:拥有方法可以修改自己的值/引用 1.以String为例的不可变类型:

一旦创建一个String对象,它会始终指向同一个值,想获得一个新的字符串,需要创建一个新的String对象 

2.StringBuilder是可变类型,能够改变对象的值 

代码快照图 3.二者的区别 当只有一个引用指向该值的时候,没有区别, 但是多个引用指向一个值的时候,可变类型就可能出现问题 当另一个变量t指向与s相同的字符串对象,而另一个变量tb指向与sb相同的字符串构建器时,那么不可变对象和可变对象之间的差异就会变得更加明显:对String t和s的操作不会影响彼此所指的值,但是对sb和tb的操作改变的是同一个值,虽然sb没有被操作,但是对tb的操作导致sb指的值变成了abc 可变类型的优势: 可变类型最少化拷贝以提高效率,可以实现多模块的数据共享(但是也要知道全局变量的缺陷),可以获得更好的性能 不可变类型:对其频繁的修改会产生大量拷贝,需要垃圾回收机制 不可变类型:更加安全,在其他质量指标上表现得更好 例子1:传入可变类型参数

在main函数中,由于List是可变类型,所以计算sumAbsolute时将myData中的负数全部改为了绝对值,因此在计算sum时,结果为10,而不是预期的-10

可变类型的风险:首先容易出现问题,它改变了参数的值,超出了spec的范畴,且这种错误很难追踪和发现

其次,这种错误也很难被程序员理解,他们不仅要阅读main的代码,还要阅读sum和sumAbsolute的具体实现

例子2:返回可变类型参数:

有两个问题:
1.Date中的month取值0-11,如果到了12月,month=11,此时再加1,变成12,再set,由于setMonth的规约限制在0-11,所以会出现问题,其次,本例Date是可变类型,partyDate和groundhogAnswer指向同一个Date,如下快照图:

那么如果多次调用startofSpring,可能导致Month不断地增加,产生错误的值

可以使用java.time包中的LocalDateTime , Instant, 它们是不可变的

或者使用防御式拷贝:
return new Date(groundhogAnswer .getTime());这种拷贝大部分时候不会被客户修改,会造成大量内存浪费

不可变类型则会节省频繁复制的代价

在局部变量上使用可变类型是安全的,因为不会共享,但是在由多个引用(别名)情况下,可变类型会变得非常不安全

防御式拷贝也会被攻击:

通过date内部的set方法改变end的年份

 四、代码快照图(run-time,moment,code level)

正在进行中的方法和本地变量在堆栈中,对象在堆中

对象值是用其类型标记的圆。–当我们想要显示更多细节时,我们在其中写字段名,箭头指向它们的值。对于更详细信息,字段可以包括它们声明的类型。

 不可变对象(其设计者希望总是表示相同的值)在快照图中用双边框表示,就像我们的图中的String字符串对象一样。

不可变的引用:双线箭头

引用是不可变的,其指向的值可以是可变的;可变的引用,也可以指向不可变的值

 对可变值的不可变引用如下:

静态检查到了final修饰的变量要改变,于是报错

还可以对不可变值进行可变引用:
 五、复杂数据类型:数组和集合

数组:定长,提前声明长度,会越界

 List:一个接口,变长,里面的成员是对象

迭代:对数组:用计数变量,从0到

对list:for each(但是不能增删元素)

Set:集合:每个对象只能在里面存有一个或不存有,方法:

 

Map:键,值成对存储

实现方式:List:LinkedList,ArrayList

Set:HashSet

Map:HashMap

Map treasures = new HashMap<>(); String x = "palm"; treasures.put("beach", 25.); treasures.put("palm", 50.); treasures.put("cove", 75.); treasures.put("x", 100.); treasures.put("palm", treasures.get("palm") + treasures.size()); treasures.remove("beach"); 代码快照图: 迭代器:可变数据类型

next()返回集合中的下一个元素,它是可变方法

hasNext()判断迭代器是否到达集合结尾 

一个迭代器实例

 代码快照图

 list双线是因为用final修饰,由于ArrayList本身是可变的,所以final并不能阻止对list内部的改变

 迭代器思想:提供一个访问元素的通用中间件,以一种统一的格式访问各种集合类

 但可变性会暗中破坏迭代器:

删除所有以“6.”开头的课程,测试用例与预期如上

 

但是实际上:最后一个用例执行结果:

 代码快照图如下:

for each此时会显示越界

使用迭代器自己的remove方法,迭代器会自动调整索引

但是不会完全解决问题,如果多个迭代器指向同一个集合类,它们之间不会告知对方各自对集合类的修改

六、不可变类型:
基本类型和它们的包裹类型都是不可变的

集合实用程序类有一些方法来获取这些可变集合的不可修改的视图:

– Collections.unmodifiableList – Collections.unmodifiableSet – Collections.unmodifiableMap 这种包装器得到的结果是不可变的:只能看 但是这种“不可变”是在运行阶段获得的,编译阶段 无法据此进行静态检查

 但是,对list的改变还是会导致对listCopy的改变:

 

不可修改的包装器有两个主要用途,如下:

在集合构建后使其不可变。在这种情况下,最好不维护对备份集合的引用。这绝对保证了不变性。允许某些客户端只读访问您的数据结构。您保留对备份集合的引用,但分发对包装器的引用。通过这种方式,客户端可以查看但不能修改,同时您保持完全访问。 

要从某些已知值创建不可变的集合,使用

List.of , Set.of , and Map.of . List a = List.of("lion", "tiger", "bear"); 或者,使用List.copyOf(Java10)来创建不可修改的可变集合的浅层副本。

 

 

 

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/952903.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号