全国协议5人面授小班,企业级独立开发考核,转业者的IT软件工程师基地 登录/注册 | 如何报名

免费领取试听课程

并获得专业顾问一对一进行选课辅导

课程名称不能为空
姓名不能为空
手机号码不能为空

领取成功

Java开发中最容易出现的几个bug

行业新闻 汉码未来 | java bug 开发

2021-10-11 09:01:43

作为Java开发工程师,在编写代码的过程中难免会产生各种奇思妙想的bug。有些bug很无奈,比如各种空指针,在ArrayList迭代导致数组下标越界异常等。

Java开发中最容易出现的几个bug

一:Array转换为ArrayList。

Array转换为ArrayList还会出错吗?

等一下,不要急,先看看发生了什么事。

在将数组转换成ArrayList时,通常的实践就是这样。

Listlist=Arrays.asList(arr);


Arrays.asList()将返回Arrays中,这是Arrays中的私有静态类,而非java.util.Arrays类。下面的图表显示了它。

Arrays中的ArrayList仅包含set、get、contains和其他方法,但不能像add那样使其内部结构发生变化,因此Arrays中Arrays中的ArrayList的大小是固定的。

若要创建一个能添加元素的ArrayList,可以使用以下创建方法:

ArrayListarrayList=newArrayList(Arrays.asList(arr));


由于ArrayList的构造方法就是能够接收Collection集合,因此可以使用此创建方法。

第二个:检查数组中是否有一个值。

一些程序员常常会检查数组中是否有特定的值:

Setset=newHashSet(Arrays.asList(arr));

returnset.contains(targetValue);

此代码尽管正确,但存在额外的性能损失,通常情况下,不需要把它重新转换成set,直接这样做就好了:

returnArrays.asList(arr).contains(targetValue);


或用下面的方法(穷举法,循环判断)

for(Strings:arr){

if(s.equals)(targetValue))

returntrue;

}

returnfalse;

上一段代码的可读性要好得多。

错误三:循环删除列表中的元素。

相信很多小伙伴都知道这个错误,在循环中删除元素是一种禁忌,有一阵子,我在审阅代码时,想看看其他的同伴是否犯过这样的错误。

那么,为什么不能这样做(在集合中移除元素)?看看下面的代码。

ArrayListlist=newArrayList(Arrays.asList("a","b","c");

for(inti=0;ilist.remove(i);

}

system.out.print(列表);

你们能想出这样的结果吗?难道要尝试一次尝试吗?

回答实际上是[b,d]

为何只有两个价值?那不是循环输出吗?

实际上,在列表中,当您使用外部remove时,一旦remove中的某个元素,其列表的内部结构就发生了变化,即集合总容量为4,remove1个元素后将变为3,然后再与i进行比较判断。因此,只有两个元素输出。

您也许知道如何使用迭代器是remove元素的正确方法,您可能也知道for-each和iterator的工作原理相似,因此您可以编写以下代码。

ArrayListlist=newArrayList(Arrays.asList("a","b","c");

for(Strings:list){

if(s.equals("a"))

list.remove(s);

}

那么你就用runxxx.main()方法吧,结果…ConcurrentModificationException。

为什么呢?

这是因为在ArrayList中使用外部的remove元素,导致了内部结构和游标的更改。

对于阿里开发规范,不能在for-each循环中使用remove/add操作来解释元素。

因此,每个人要用List来增加或删除元素,确保要用迭代器删除。也就是

.next()必须在.remove()之前调用。在foreach循环中,编译器在删除元素的操作之后调用.next(),从而产生ConcurrentModificationException。

差错四:Hashtable和HashMap。

这里有关于算法的规定:Hashtable是一个数据结构的名字,根据算法的惯例,但在Java中,数据结构的名称为HashMap,Hashtable和HashMap之间的一个主要差异在于Hashtable是同步的,因此很多情况下您不需要Hashtable,而用HashMap。

错误5:使用原始类型的集合。

它是一种一般方面的约束:

原始类型和无边界通配符类型在Java中可以轻松混合。对于Set,Set是原始类型,Set是无界通配符类型。

例如以下代码将原始类型List用作参数:

publicstaticvoidadd(法律法规){

list.add(o);

}

publicstaticvoidmain(String[]args){

列表=newArrayList();

add(列表,10);

Strings=list.get(0);

}

这个代码引发java.lang.ClassCastException异常,为什么?

与原始类型的集合相比更危险,因为原始类型将跳过泛型检查并且不安全,Set、Set和Set之间有很大差异,并且泛型在使用中容易导致类型清除。

众所周知,Java的泛型是伪泛型,这是因为Java在编译过程中,所有泛型信息都会被清除,正确理解泛型概念的第一个前提就是要了解类型清除。Java的泛型基本上都是在编译器这一层实现的,结果字节码中没有泛型类型信息,泛型使用时加上类型参数,编译器编译时会将其去掉,此过程变成类型擦除。

像定义List和List这样的代码,在编译之后就变成了List,JVM只看到List,而JVM所看到的类型信息对于JVM来说是不存在的。Java编译器在编译时会尽可能地找到可能发生的错误,但在运行时间内仍然不能发生的类型转换异常,而类型清理是Java的泛型和C++模板机制实现方式之间的一个重要差异。


以上就是汉码未来给大家分享的文章,希望对小伙伴们有所帮助,想要了解更多Java开发中最容易出现的几个bug相关内容的小伙伴可以登录汉码未来官网咨询,主打5人小班,全程面授,主打Java开发,web前端开发等课程,有专业的授课老师为你答疑解惑。

    

分享到:



【免责声明】由于政策等各方面情况的不断调整与变化,本网站所提供的信息仅供参考,请以权威部门公布的正式信息为准。本网站在文章内容来源出处标注为其他平台的稿件均为转载稿,免费转载出于非商业性学习目的,版权归原作者所有。如您对内容、版权等问题存在异议请与本站联系,我们会及时进行处理解决。 删除,请联系客服。
相关推荐
为什么选择汉码未来