和绝大多数的程序员一样,我也非常的宅。周末最奢侈的享受就是逛一逛技术型网站,比如说 programcreek,这个小网站上有一些非常有意思的主题。比如说:Java 程序员最常犯的错竟然是这 10 个,像这类令人好奇心想害死猫的主题,非常值得扒出来给大家分享一下。


PS:别问“为什么标题要加上‘惊呆了’?”问了答案就只有一个——吓唬人——总得勾起大家的阅读兴趣嘛(我容易吗我)。

01、把 Array 转成 ArrayList

说实在的,很多 Java 程序员喜欢把 Array 转成 ArrayList:

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

但实际上,Arrays.asList() 返回的 ArrayList 并不是 java.util.ArrayList,而是 Arrays 的内部私有类 java.util.Arrays.ArrayList。虽然名字完全相同,都是 ArrayList,但两个类有着很大的不同。Arrays.ArrayList 虽然有 set()get()contains() 等方法,但却没有一个方法用来添加元素,因此它的大小是固定的。

如果想创建一个真正的 ArrayList,需要这样做:

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

ArrayList 的构造方法可以接收一个 Collection 类型的参数,而 Arrays.ArrayList 是其子类,所以可以这样转化。

02、通过 Set 检查数组中是否包含某个值

之前我在写一篇文章《如何检查Java数组中是否包含某个值》中曾提到一种方法:

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

这种方法确实可行,但却忽视了性能问题;为了能够尽快完成检查,可以这样做:

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

或者使用普通的 for 循环或者 for-each。

03、通过 for 循环删除列表中的元素

新手特列喜欢使用 for 循环删除列表中的元素,就像这样:

List<String> list = new ArrayList<String>(Arrays.asList("沉", "默", "王", "二"));
for (int i = 0; i < list.size(); i++) {
    list.remove(i);
}
System.out.println(list);

上面这段代码的目的是把列表中的元素全部删除,但结果呢:

[默, 二]

竟然还有两个元素没删除,why?

当 List 的元素被删除时,其 size() 会减小,元素的下标也会改变,所以想通过 for 循环删除元素是行不通的。

那 for-each 呢?

for(String s : list) {
    if ("沉".equals(s)) {
       list.remove(s);
    }
}

System.out.println(list);

竟然还抛出异常了:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
    at java.util.ArrayList$Itr.next(ArrayList.java:859)
    at com.cmower.java_demo.programcreek.Top10Mistake.main(Top10Mistake.java:15)

抛出异常的原因,可以查看我之前写的文章《Java,你告诉我 fail-fast 是什么鬼?》。

有经验的程序员应该已经知道答案了,使用 Iterator:

Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
    String s = iter.next();

    if (s.equals("沉")) {
        iter.remove();
    }
}

System.out.println(list);

程序输出的结果如下:

[默, 王, 二]

04、使用 Hashtable 而不是 HashMap

通常来说,哈希表应该是 Hashtable,但在 Java 中,哈希表通常指的是 HashMap。两者之间的区别之一是 Hashtable 是线程安全的。如果没有特殊要求的话,哈希表应该使用 HashMap 而不是 Hashtable。

05、使用原始类型

在 Java 中,新手很容易混淆无限通配符和原始类型之间的差别。举例来说,List<?> list 为无限通配符,List 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, 18);
    add(list, "沉默王二");
    String s = list.get(0);
}

这段代码在运行时会抛出异常:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    at com.cmower.java_demo.programcreek.Top10Mistake.main(Top10Mistake.java:38)

使用原始类型非常的危险,因为跳过了泛型的检查。至于 List<Object>List 之间的区别,查看我写的另外一篇文章:《为什么不应该使用Java的原始类型》。

06、使用 public 修饰字段

有些新手喜欢使用 public 修饰字段,因为不需要 getter/setter 方法就可以访问字段。但实际上,这是一个非常糟糕的设计;有经验的程序员更习惯于提供尽可能低的访问级别。

07、使用 ArrayList 而不是 LinkedList

新手往往搞不清楚 ArrayList 和 LinkedList 之间的区别,因此更倾向于使用 ArrayList,因为比较面熟。但是呢,它们之间存在巨大的性能差异。简单的说吧,如果“添加/删除”的操作比较多,而“获取”的操作比较少,则应该首选 LinkedList。

08、使用过多的不可变对象

不可变对象有着不少的优点,比如说简单性和安全性。但是呢,如你所料,它也有一些难以抗拒的弊端:对于每一个不同的值,它都需要一个单独的对象来表示,这样的对象太多的话,很可能会导致大量的垃圾,回收的成本就变得特别高。

为了在可变与不可变之间保持平衡,通常会使用可变对象来避免产生太多中间对象。一个经典的例子就是使用 StringBuilder(可变对象) 来连接大量的字符串,否则的话,String(不可变对象)会产生很多要回收的垃圾。

反例:

String result="";
for(String s: arr){
    result = result + s;
}

正例:

StringBuilder result = new StringBuilder();
for (String s: strs) {
    result.append(s);
}

参考文章:为什么 Java 字符串是不可变的?

09、父类没有默认的无参构造方法

在 Java 中,如果父类没有定义构造方法,则编译器会默认插入一个无参的构造方法;但如果在父类中定义了构造方法,则编译器不会再插入无参构造方法。所以下面的代码会在编译时出错。


子类中的无参构造方法试图调用父类的无参构造方法,但父类中并未定义,因此编译出错了。解决方案就是在父类中定义无参构造方法。


10、使用构造方法创建字符串

创建字符串有两种方法:

1)使用双引号

String er = "沉默王二";

2)使用构造方法

String san = new String("沉默王三");

但是它们之间有着很大的不同(可以参照创建 Java 字符串,用""还是构造函数),双引号被称为字符串常量,可以避免重复内容的字符串在内存中创建。


好了,读者朋友们,以上就是本文的全部内容了。可以掏心窝子地说,没有任何客观的数据来证明它们就是前十名,但绝对非常普遍。如果不认可其中的内容,请在留言区轻喷,好人有好报。如果觉得不过瘾,还想看到更多,可以 star 二哥的 GitHub【itwanger.github.io】,本文已收录。

原创不易,如果觉得有点用的话,请不要吝啬你手中点赞的权力——这将是我最强的写作动力。

惊呆了!Java程序员最常犯的错竟然是这10个的更多相关文章

  1. Java程序员最常犯的错误盘点之Top 10

    1. 数组转ArrayList 为了实现把一个数组转换成一个ArrayList,很多Java程序员会使用如下的代码: Arrays.asList确实会返回一个ArrayList对象,但是该类是Arra ...

  2. 细数那些Java程序员最容易犯那些错

    java作为最受欢迎程度榜榜首语言,自然是广大开发者使用最多的语言.正因为有如此广泛的使用性,java开发中发生异常也比比皆是,接下来我们就来看看那些java开发中最容易出现的那些错误. 1.重复造轮 ...

  3. C# 程序员最常犯的 10 个错误(转)

    关于C#关于本文常见错误 #1:把引用当做值来用,或者反过来常见错误 #2:误会未初始化变量的默认值常见错误 #3:使用不恰当或未指定的方法比较字符串常见错误 #4:使用迭代式 (而不是声明式)的语句 ...

  4. C# 程序员最常犯的 10 个错误http://www.oschina.net/translate/top-10-mistakes-that-c-sharp-programmers-make

    来源:http://www.oschina.net/translate/top-10-mistakes-that-c-sharp-programmers-make 关于C# C#是达成微软公共语言运行 ...

  5. C# 程序员最常犯的 10 个错误

    关于C# C#是达成微软公共语言运行库(CLR)的少数语言中的一种.达成CLR的语言可以受益于其带来的特性,如跨语言集成.异常处理.安全性增强.部件组合的简易模型以及调试和分析服务.作为现代的CLR语 ...

  6. 惊呆!Java程序员等级一览

      凡人:买本书凑凑热闹,听得多写的少,过段时间就把老师教的都忘了.这个阶段是刷掉人最多的阶段,也是从凡人到程序员本质区别的阶段.你的日后成就在于你的习惯与态度.隔一段时间整理自己的知识体系是重中之重 ...

  7. PHP程序员最常犯的11个MySQL错误

    对于大多数web应用来说,数据库都是一个十分基础性的部分.如果你在使用PHP,那么你很可能也在使用MySQL—LAMP系列中举足轻重的一份子. 对于很多新手们来说,使用PHP可以在短短几个小时之内轻松 ...

  8. Java程序员常犯的10个错误

      本文总结了Java程序员常犯的10个错误. #1. 把Array转化成ArrayList 把Array转化成ArrayList,程序员经常用以下方法: List<String> lis ...

  9. Java 程序员在写 SQL 时常犯的 10 个错误

    Java程序员编程时需要混合面向对象思维和一般命令式编程的方法,能否完美的将两者结合起来完全得依靠编程人员的水准: 技能(任何人都能容易学会命令式编程) 模式(有些人用“模式-模式”,举个例子,模式可 ...

随机推荐

  1. 12 Top Open Source Data Analytics Apps

    1. Hadoop It would be impossible to talk about open source data analytics without mentioning Hadoop. ...

  2. behavior planning——14.implement a cost function in C++

    n most situations, a single cost function will not be sufficient to produce complex vehicle behavior ...

  3. poj 1039 Pipe (Geometry)

    1039 -- Pipe 理解错题意一个晚上._(:з」∠)_ 题意很容易看懂,就是要求你求出从外面射进一根管子的射线,最远可以射到哪里. 正解的做法是,选择上点和下点各一个,然后对于每个折点位置竖直 ...

  4. SuperSocket 服务器管理器客户端

    SuperSocket 服务器管理器当前有两种类型的客户端, Silverlight客户端和WPF客户端.这两种客户端的代码都在源代码中的"Management"目录,你可以自行编 ...

  5. Python:pip 和pip3的区别

    前言 装完python3后发现库里面既有pip也有pip3,不知道它们的区别,因此特意去了解了一下. 解释 先搜索了一下看到了如下的解释, 安装了python3之后,库里面既会有pip3也会有pip ...

  6. 学习PHP好,还是Python好呢?

    首先简单介绍一下Python. Python在出现以来,已经有数以千计基于这项技术的网站和软件项目,Python因其独有的特点从众多开发语言中脱颖而出,深受世界各地的开发者喜爱. 下面,我们列举了Py ...

  7. halcon坐标转换(机器人坐标转换用)

    #图像坐标r:=[431, 355, 507, 53, 507]c:=[505, 543, 316, 127, 883]#物理坐标(例如机器人坐标)r1:=[0, 2.0, -2.0, 10, -2. ...

  8. codedecision P1112 区间连续段 题解 线段树

    题目描述:https://www.cnblogs.com/problems/p/P1112.html 题目链接:http://codedecision.com/problem/1112 线段树区间操作 ...

  9. Python--day29--logging模块(日志模块)

    重要程度六颗星,比如一个小窗口的广告如果因为你没有日志的问题导致点击量没有记录下来,几十分钟那就会损失几十万了,这责任谁负得起. 希望离开一个公司是因为有了更好的去处而不是因为各种各样的原因被开掉,那 ...

  10. Python--day44--navicat使用(知道怎么用就好,要用终端操作,用这个会被人鄙视)