10个Java开发人员最常犯的错误

news2024/9/28 11:15:27

这个列表总结了10个Java开发人员最常犯的错误,是我基于大量的github上的开源项目,Stack overflow上的问题,还有一些流行的google搜索的分析,没有明显示的评估证明它们是前10,但它们绝对是很常见的。

1.Array转ArrayList

当需要把Array转成ArrayList的时候,开发人员经常这样做:

List<String> list = Arrays.asList(arr);

Arrays.asList()会返回一个ArrayList,但是要特别注意,这个ArrayList是Arrays类的静态内部类,并不是java.util.ArrayList类。java.util.Arrays.ArrayList类实现了set(), get(),contains()方法,但是并没有实现增加元素的方法(事实上是可以调用add方法,但是没有具体实现,仅仅抛出UnsupportedOperationException异常),因此它的大小也是固定不变的。为了创建一个真正的java.util.ArrayList,你应该这样做:

ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));

ArrayList的构造方法可以接收一个Collection类型,而java.util.Arrays.ArrayList已经实现了该接口。

2.判断一个数组是否包含某个值

开发人员经常这样做:

Set<String> set = new HashSet<String>(Arrays.asList(arr));

return set.contains(targetValue);

以上代码可以正常工作,但是没有必要将其转换成set集合,将一个List转成Set需要额外的时间,其实我们可以简单的使用如下方法即可:

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

或者

for(String s: arr){

if(s.equals(targetValue))

return true;

}

return false;

第一种方法可读性更强。

3.在循环内部删除List中的一个元素

考虑如下代码,在迭代期间删除元素:

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c","d"));

for (int i = 0; i < list.size(); i++) {

list.remove(i);

}

System.out.println(list);

结果打印:

[b, d]

在上面这个方法中有一系列的问题,当一个元素被删除的时候,list大小减小,然后原先索引指向了其它元素。所以如果你想在循环里通过索引来删除多个元素,将不会正确工作。

你也许知道使用迭代器是在循环里删除元素的正确方式,或许你也知道foreach循环跟迭代器很类似,但事实情况却不是这样,如下代码:

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c","d"));

for (String s : list) {

if (s.equals("a"))

list.remove(s);

}

将抛出ConcurrentModificationException异常。

然而接下来的代码却是OK的:

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c","d"));

Iterator<String> iter = list.iterator();

while (iter.hasNext()) {

String s = iter.next();

if (s.equals("a")) {

iter.remove();

}

}

next()方法需要在remove()方法之前被调用,在foreach循环里,编译器会在删除元素操作化调用next方法,这导致了ConcurrentModificationException异常。更多详细信息,可以查看ArrayList.iterator()的源码。

4.HashTable与HashMap

从算法的角度来讲,HashTable是一种数据结构名称。但是在Java中,这种数据结构叫做HashMap。HashTable与HashMap的一个主要的区别是HashTable是同步的,所以,通常来说,你会使用HashMap,而不是Hashtable。

5.使用集合原始类型(raw type)

在Java中,原始类型(raw type)和无界通配符类型很容易让人混淆。举个Set的例子,Set是原始类型,而Set<?>是无界通配符类型。

请看如下代码,add方法使用了一个原始类型的List作为入参:

public static void add(List list, Object o){

list.add(o);

}

public static void main(String[] args){

List<String> list = new ArrayList<String>();

add(list, 10);

String s = list.get(0);

}

运行以上代码将会抛出异常:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

at ...

使用原始类型集合非常危险,因为它跳过了泛型类型检查,是不安全的

6.访问级别

开发人员经常使用public修饰类字段,虽然这很容易让别人直接通过引用获取该字段的值,但这是一个不好的设计。根据经验,应该尽可能的降低成员属性的访问级别。

7.ArrayList和LinkedList

为什么开发人员经常使用ArrayList和LinkedList,却不知道他们之间的区别,因为它们看起来很像。然而它们之间有着巨大的性能差异。简单的说,如果有大量的增加删除操作并且没有很多的随机访问元素的操作,应该首选LinkedList。

8.可变与不可变

不可变对象有很多优点,如简单、安全等。但是对于每个不同的值都需要一个单独的对象,太多的对象会引起大量垃圾回收,因此在选择可变与不可变的时候,需要有一个平衡。

通常,可变对象用于避免产生大量的中间对象,一个经典的例子是大量字符串的拼接。如果你使用一个不可变对象,将会马上产生大量符合垃圾回收标准的对象,这浪费了CPU大量的时间和精力。使用可变对象是正确的解决方案(StringBuilder);

String result="";

    for(String s: arr){

    result = result + s;

}

另外,在有些其它情况下也是需要使用可变对象。例如往一个方法传入一个可变对象,然后收集多种结果,而不需要写太多的语法。另一个例子是排序和过滤:当然,你可以写一个方法来接收原始的集合,并且返回一个排好序的集合,但是那样对于大的集合就太浪费了。

9.父类和子类的构造方法

之所以出现这个编译错误,是因为父类的默认构造方法未定义。在Java中,如果一个类没有定义构造方法,编译器会默认插入一个无参数的构造方法;但是如果一个构造方法在父类中已定义,在这种情况,编译器是不会自动插入一个默认的无参构造方法,这正是以上demo的情况;

对于子类来说,不管是无参构造方法还是有参构造方法,都会默认调用父类的无参构造方法;当编译器尝试在子类中往这两个构造方法插入super()方法时,因为父类没有一个默认的无参构造方法,所以编译器报错;

要修复这个错误,很简单:

1、在父类手动定义一个无参构造方法:

public Super(){

    System.out.println("Super");

}

2、移除父类中自定义的构造方法

3、在子类中自己写上父类构造方法的调用;如super(value);

10.“”还是构造方法

有两种创建字符串的方式:

//1. use double quotes

String x = "abc";

//2. use constructor

String y = new String("abc");

它们之间有什么区别呢?

以下代码提供了一个快速回答:

String a = "abcd";

String b = "abcd";

System.out.println(a == b); // True

System.out.println(a.equals(b)); // True

String c = new String("abcd");

String d = new String("abcd");

System.out.println(c == d); // False

System.out.println(c.equals(d)); // True

正文结束

-点赞是最大的支持

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/438704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络-IP地址计算专题(非常重要)

文章目录 IP地址快速计算法则IP计算例题1(给出了子网掩码)IP计算例题2(给出了建网比特数)求划分子网的个数求划分N个子网之后的子网掩码子网的划分超网聚合变形&#xff0c;求子网地址的规律假如让你设计网络 IP地址快速计算法则 软考中的地址计算题都只需要计算出某个IP地址所…

港联证券|万亿级AIGC赛道或迎有序监管

近段时间&#xff0c;连续有国内外科技巨子涌入万亿级AIGC&#xff08;生成式AI&#xff09;赛道&#xff0c;A股商场上AIGC、ChatGPT等人工智能相关概念也是继续火热。但与此同时&#xff0c;安全隐患也如冰山一角逐渐露出。多国政府正在考虑加强对其监管&#xff0c;AIGC在全…

时刻警惕!企业如何全面应对攻击战术演进

Fortinet FortiGuard Labs &#xff08;Fortinet全球威胁研究与响应实验室&#xff09;发布的 《全球威胁态势研究报告-2022年下半年》显示&#xff0c;不法分子正将更多资源投入至MITRE ATT&CK “前期侦察”和“武器构建”两大战术阶段&#xff0c;组织必须时刻提高警惕&a…

“QT 快速上手指南“ 之 计算器(三)信号与槽,connect 函数,QString

文章目录 前言一、什么是信号与槽&#xff1f;二、QObject::connect 函数三、QT 中的字符串类 QString1. 创建和初始化字符串&#xff1a;2. 字符串的拼接和添加3. 字符串的查找和替换4. 字符串的分割和处理 总结 前言 QT 中 信号 与 槽机制&#xff08;Signal and Slot&#…

Project1:Boolean Logic

目录 Part1:Lecture && bookunit 1.1 Boolean Logicunit 1.2 boolean function synthesisunit 1.3 logic gatesunit 1.4 Hardware Description languageunit 1.5 Hardware simulationunit 1.6 Multi-bit Buses part2:Project Part1:Lecture && book unit 1.1 …

Invalid bound statement (not found):报错解决方法

报错信息&#xff1a; Invalid bound statement (not found): com.atguigu.auth.mapper.SysMenuMapper.findMenuListByUserId 因为&#xff1a;maven加载机制 maven默认情况下&#xff0c;只会加载编译ser-main-java目录里面java类型文件&#xff0c;其他类型文件不会进行加…

如何利用在线帮助中心解决客户问题?

随着互联网的不断发展&#xff0c;越来越多的企业意识到客户服务的重要性。然而&#xff0c;如何提供高效、可靠、贴心的客户服务一直是企业面临的难题。在这个背景下&#xff0c;在线帮助中心应运而生。本文将介绍如何利用在线帮助中心解决客户问题&#xff0c;让企业更好地提…

中交二公局的数字化转型之路:微信扫一扫即可轻松巡检

中交二公局主要从事路桥施工等业务&#xff0c;具有公路工程施工总承包特级资质&#xff0c;是一家集铁路、隧道、机场、水工、市政、工程施工设计、咨询、监理等为一体的大型国有施工企业。 自成立以来&#xff0c;中交二公局在工程施工领域积累了丰富的经验&#xff0c;业务…

【java】maven引用外部 jar 包,以RXTXcomm.jar为例

目录 1.作为资源文件夹内的资源引用2.将jar包手动安装到maven仓库 工具&#xff1a;IntelliJ IDEA 2020.2.3 x64 1.作为资源文件夹内的资源引用 1.在项目根路径新建文件夹lib, 将资源文件复制到该文件夹。 2.将文件夹设置为资源文件夹&#xff1a;选中文件夹lib右键 -> Mak…

vscode + python + jupyter notebook环境配置

参考网络上的大神文章&#xff0c;在公司PC上搭建Pythonvscode环境&#xff0c;做一下记录。 安装环境参考如下文章&#xff1a; https://blog.csdn.net/qq_52271115/article/details/126773282 安装完毕Python后&#xff0c;我公司的电脑需要额外将下面两个环境变量添加到 …

出苗率相关论文

文章目录 2021A UAV Open Dataset of Rice Paddies for Deep Learning PracticeAutomatic UAV-based counting of seedlings in sugar-beet field and extension to maize and strawberry(Computers and Electronics in Agriculture) 2022Detection and Counting of Maize Leav…

6D目标检测简述

6D目标检测简述 文章目录 6D目标检测简述介绍基于模版匹配的算法基于点的算法基于描述子的算法基于特征的算法 基于深度学习的6D姿态估计基于RGB图像的深度学习方法**SSD-6D****Deep-IM****PV-Net****HybridPose****Self6D****DSC-PoseNet****GDR-Net****SO-Pose****KDF-Net** …

一文搞定接口幂等性架构设计方案

幂等性介绍 现如今很多系统都会基于分布式或微服务思想完成对系统的架构设计。那么在这一个系统中&#xff0c;就会存在若干个微服务&#xff0c;而且服务间也会产生相互通信调用。那么既然产生了服务调用&#xff0c;就必然会存在服务调用延迟或失败的问题。当出现这种问题&am…

VIP + Nginx + Keepalived

VIP&#xff08;Virtual IP Address&#xff09;&#xff0c;虚拟IP地址&#xff0c;主要是用来进行不同主机之间的切换&#xff0c;主要用在服务器的主从切换技术。主从服务器都配置同一个VIP地址&#xff0c;保障系统不间断切换。 Keepalived是高可用解决方案&#xff0c;借助…

Zookeeper源码分析——ZK服务端加载数据源码解析

ZK服务端加载数据源码解析 &#xff08;1&#xff09;zk 中的数据模型&#xff0c;是一棵树&#xff0c;DataTree&#xff0c;每个节点&#xff0c;叫做DataNode &#xff08;2&#xff09;zk 集群中的DataTree 时刻保持状态同步 &#xff08;3&#xff09;Zookeeper 集群中每个…

现代化生态灌区智慧灌溉管理系统-中小灌区节水改造

系统概述 现代化生态灌区智慧灌溉管理系统主要对对灌区的水情、雨情、土壤墒情、气象等信息进行监测&#xff0c;对重点区域进行视频监控&#xff0c;同时对泵站、闸门进行远程控制&#xff0c;实现了信息的测量、统计、分析、控制、调度等功能。为灌区管理部门科学决策提供了依…

SpringCloud断路器——Hystrix

Hystrix 本专栏学习内容来自尚硅谷周阳老师的视频 有兴趣的小伙伴可以点击视频地址观看 简介 Hystrix是一个用于处理分布式系统的延迟和容错的一个开源库&#xff0c;在分布式系统里&#xff0c;许多依赖不可避免的会调用失败&#xff0c;比如超时、异常等&#xff0c;Hystrix…

React context 用法

Context 提供了一个无需为每层组件手动添加 props&#xff0c;就能在组件树间进行数据传递的方法。 1. 用法 React.createContext const MyContext React.createContext(defaultValue);创建一个 Context 对象。当 React 渲染一个订阅了这个 Context 对象的组件&#xff0c;…

服务(第六篇)LNMP

第一步、安装nginx&#xff1a; 前期准备&#xff1a; 安装依赖环境&#xff1a; 创建nginx用户和解压&#xff1a; 编译安装nginx&#xff1a; 优化&#xff1a; 进入/usr/local/systemd/system创建nginx.service&#xff08;开启nginx服务&#xff09; 结果&#xff1a; 第…

Vector - CAPL - Panel面板_03

CheckBox 功能&#xff1a;复选框可以用作控制和显示元素&#xff0c;使用它可以启动、显示、使能等选项。 适用场景&#xff1a; 1、特定场景触发某些使能信号&#xff0c;例如转速达到5000r/mi后使能Checkbox&#xff0c;触发错误场景等 2、亦或者将信号设置为特定的值。 3、…