文档章节

Java开发者易犯错误Top10

kingdelee
 kingdelee
发布于 2015/02/15 23:00
字数 1810
阅读 10
收藏 0
点赞 0
评论 0

本文总结了Java开发者经常会犯的前十种错误列表。


Top1. 数组转换为数组列表

将数组转换为数组列表,开发者经常会这样做:

[java] view plaincopy

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

Arrays.asList()将返回一个数组内部是私有静态类的ArrayList,这不是java.util.ArrayList类,java.util.Arrays.ArrayList类有set()、 get()、 contains()方法,但是没有任何加元素的方法,因此它的大小是固定的。你应该这么做来创建一个真正的数组:

[java] view plaincopy

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

ArrayList的构造函数能够接受一个集合类型,这也是java.util.Arrays.ArrayList的超级类型。

Top2. 检查一个数组包含一个值

开发者经常这么做:

[java] view plaincopy

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

  2. return set.contains(targetValue);  

代码可以工作,但是没有必要首先转换列表到Set,转换一个列表到一个Set需要额外的时间。因此你可以把它简化为:

[java] view plaincopy

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

[java] view plaincopy

  1. for(String s: arr){  

  2.     if(s.equals(targetValue))  

  3.         return true;  

  4. }  

  5. return false;  

第一个比第二个更具可读性

Top3. 在一个循环中从一个列表里删除一个元素

考虑下面删除元素的代码在迭代中的结果:

[java] view plaincopy

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

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

  3.     list.remove(i);  

  4. }  

  5. System.out.println(list);  

输出是:

[java] view plaincopy

  1. [b, d]  

该方法有一个严重的问题,当一个元素被删除时,列表收缩的大小以及指针改变了。所以想要在循环内利用指针删除多个元素是无法正常进行的。

这种情况下使用迭代器才是正确的方法,foreach循环在Java中的工作像是一个迭代器,但实际上并不是,考虑下面的代码:

[java] view plaincopy

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

  2.    

  3. for (String s : list) {  

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

  5.         list.remove(s);  

  6. }  

它会报出ConcurrentModificationException异常。

相反下面这个就可以正常工作。

[java] view plaincopy

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

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

  3. while (iter.hasNext()) {  

  4.     String s = iter.next();  

  5.    

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

  7.         iter.remove();  

  8.     }  

  9. }  

.next()必须在.remove()之前被调用。在foreach循环中,编译器将在删除元素操作之后调用.next(),这也是导致ConcurrentModificationException异常的原因,你可以点击此处查看ArrayList.iterator()的源代码。

Top4. Hashtable vs HashMap

根据算法的常规,Hashtable是对数据结构的称呼。但是在Java中,数据结构的名称是HashMap。Hashtable和HashMap关键不同之一是Hashtable是同步的。

关于这一点可查看以下两个链接:

HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap

Map问题Top10

Top5. 使用集合的原始类型

在Java中,原始类型和无限制的通配符类型很容易被混淆。以Set为例,Set是原始类型,而Set(?)则是无限制的通配符类型。

考虑下面的代码,以一个原始类型List作为参数:

[java] view plaincopy

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

  2.     list.add(o);  

  3. }  

  4. public static void main(String[] args){  

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

  6.     add(list, 10);  

  7.     String s = list.get(0);  

  8. }  

该代码会抛出一个异常:

[java] view plaincopy

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

  2.     at ...  

使用原始类型集合是危险的,因为原始类型集合跳过了泛型类型检查,也不安全。Set、Set<?>和Set<Object>之间有很大的不同。详细可查看

Raw type vs. Unbounded wildcardType Erasure

Top6. 访问级别

开发者经常对类域使用public,这很容易通过直接引用获得域值,但这是一个非常糟糕的设计。根据经验来说是给予成员的访问级别越低越好。

详细情况可点击查看Java中成员访问级别:public、protected、private

Top7.ArrayList VS LinkedList

如果你不知道ArrayList和LinkedList之间的区别时,你可能会经常的选用ArrayList,因为它看起来看熟悉。然而它们之间有巨大的性能不同。简单的来说,如果有大量的添加/删除操作,并且没有很多的随机存取操作时,LinkedList应该是你的首选。如果您对此不是很了解的话,点此此处查看更多关于它们性能的信息。

Top8. Mutable VS Immutable

Immutable对象有很多优势,比如简单、安全等等。但它要求每一个不同的值都需要有一个不同的对象,而太多的对象可能会导致垃圾收集的高成本。所以对Mutable和Immutable的选择应该有一个平衡点。

一般来说,Mutable对象用于避免产生过多的中间对象,经典的例子是连接大量的字符串数。如果你使用Immutable字符串,那么会产生很多符合垃圾收集条件的对象。这对CPU是浪费时间和精力的,当其可以使用Mutable对象作为正确的解决方案。(如StringBuilder)

[java] view plaincopy

  1. String result="";  

  2. for(String s: arr){  

  3.     result = result + s;  

  4. }  

这里还有一些其他Mutable对象可取的情况。例如mutable对象传递到方法中允许你在不跳过太多语法的情况下收集多个结果。另一个例子是排序和过滤,你可以构建一个带有原有集合的方法,并返回一个已排序的,不过这对大的集合来说会造成更大的浪费。

推荐阅读:为什么字符串是Immutable?

Top9. Super和Sub构造函数


这个编译错误是因为默认的Super构造函数是未定义的。在Java中,如果一个类没有定义一个构造函数,编译器会默认的为类插入一个无参数构造函数。如果一个构造函数是在Super类中定义的,这种情况下Super(String s),编译器不会插入默认的无参数构造函数。

另一方面,Sub类的构造函数,无论带不带有参数,都会调用无参数的Super构造函数。

编译器在Sub类中试图将Super()插入到两个构造函数中,但是Super默认的构造函数是没有定义的,编译器才会报错。如何解决这一问题?你只需在Super类中添加一个Super()构造函数,如下所示:

[java] view plaincopy

  1. public Super(){  

  2.     System.out.println("Super");  

  3. }  

或移除自定义的Super构造函数,又或者在Sub函数中添加super(value)。

这方面想了解更多的可以点击此处查看。

Top10. ""或构造函数?

字符串可以通过两种方式创建:

[java] view plaincopy

  1. //1. use double quotes  

  2. String x = "abc";  

  3. //2. use constructor  

  4. String y = new String("abc");  

它们之间有何不同?下面的例子可以给出答案:

[java] view plaincopy

  1. String a = "abcd";  

  2. String b = "abcd";  

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

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

  5.    

  6. String c = new String("abcd");  

  7. String d = new String("abcd");  

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

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

关于它们如何在内存中分布的更多细节可以查看《使用""或构造函数创建Java字符串》。

推荐阅读:

Constructors of Sub and Super Classes in Java?

How Developers Sort in Java?

How to Convert Array to ArrayList in Java?

Java Type Erasure Mechanism

原文来自:programcreek

本文为CSDN编译整理,未经允许不得转载,如需转载请联系market#csdn.net(#换成@)

http://www.csdn.net/article/2015-02-13/2823958

本文转载自:http://www.csdn.net/article/2015-02-13/2823958

共有 人打赏支持
kingdelee
粉丝 4
博文 68
码字总数 44593
作品 0
朝阳
程序员
struts2+hibernate3.2+spring2.5+tomcat6+sqlserver2000+jndi配置

搞了两天的东西原来只有几行代码,就解决问题了,真是让自己啼笑皆非。折腾了1天之久,不想后面的朋友继续走上我的错误之路,把过程给贴出来。 1、添加struts2&&hibernate3.2&&spring2.5 所需...

loowj
2010/08/08
0
0
JVM性能优化, Part 5:Java的伸缩性

ImportNew注: JVM性能优化系列文章前4篇由ImportNew翻译(第一篇,第二篇,第三篇, 第四篇)。本文由新浪微博:吴杰 (@WildJay) 投稿至ImportNew。感谢吴杰! 如果你希望分享好的原创文章或...

梁杰_Jack
2014/10/30
0
0
使用ConcurrentMap实现高效可靠的原子操作

问题:服务器S1从远程获取多个文件到本地处理。这些文件的数据会被Processor转换成不同类型的数据模型存放至S1的数据库。每个Processor处理逻辑是相互独立的,但是同一个文件的数据可能会被多...

屈想顺
06/14
0
0
分享几个JAVA程序员们最容易犯的错误,你中了几枪?

都说Java语言是一门简单的编程语言,基于C++演化而来,剔除了很多C++中的复杂特性,但这并不能保证Java程序员不会犯错。那么对于广大的Java程序员来说,它们最常犯的几个错误都是什么样的呢?...

启示录是真的
05/25
0
0
java.lang.NoClassDefFoundError解决方案

首先:java.lang.NoClassDefFoundError是运行是错误,编译的时候不报错。这与java.lang.ClassNotfoundException是不一样的。 解决方法 第一种,也是新手容易犯的错误,那就是classpath环境变量...

anlen_gzz
2015/11/12
0
0
IBM和SAP开源其JVM诊断工具

IBM最近发布了其Java诊断工具套件,该套件包含如下工具:面向Java的产品转储分析器(Dump Analyzer)、处理垃圾收集(GC,即Garbage Collection)的Extensible Verbose Toolkit和Java锁分析器...

JavaGG
2010/03/24
0
0
Java编程基础知识点和技术点归纳

Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互...

Java小辰
05/23
0
0
我对Objective-C中一个方法如何传递多个参数的理解

原来如此 Objective-C语法中多参数传递方法经常是初学者最容易犯困的地方。我自己也是刚刚悟出来与大家分享. 分析 由于我们已有的语言经验告诉我们定义方法都是: 例如: C/C++ JAVA C#(跟Jav...

花米
2013/11/22
0
6
JAVA开发者应该去的20个英文网站

JAVA开发者应该去的20个英文网站 2005-09-12 14:28 shiqiang124 CSDN 我要评论(0) 字号:T | T 为JAVA开发者推荐应该去的20个英文网站! AD: WOT2014课程推荐:实战MSA:用开源软件搭建微服...

对岸
2014/05/26
0
0
CentOS 6.5(64bit)上部署Android开发环境

一、系统配置 公司的电脑,使用了一段时间后又换了其他系统,在此记录下配置的过程。 使用ROOT权限登陆 二、前期配置 HOST配置 在hosts文件中添加 下载32位lib库 http://www.eclipse.org/dow...

steve.ming
2014/03/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Android 复制和粘贴功能

做了一回搬运工,原文地址:https://blog.csdn.net/kennethyo/article/details/76602765 Android 复制和粘贴功能,需要调用系统服务ClipboardManager来实现。 ClipboardManager mClipboardM...

她叫我小渝
今天
0
0
拦截SQLSERVER的SSL加密通道替换传输过程中的用户名密码实现运维审计(一)

工作准备 •一台SQLSERVER 2005/SQLSERVER 2008服务 •SQLSERVER jdbc驱动程序 •Java开发环境eclipse + jdk1.8 •java反编译工具JD-Core 反编译JDBC分析SQLSERVER客户端与服务器通信原理 SQ...

紅顏為君笑
今天
6
0
jQuery零基础入门——(六)修改DOM结构

《jQuery零基础入门》系列博文是在廖雪峰老师的博文基础上,可能补充了个人的理解和日常遇到的点,用我的理解表述出来,主干出处来自廖雪峰老师的技术分享。 在《零基础入门JavaScript》的时...

JandenMa
今天
0
0
linux mint 1.9 qq 安装

转: https://www.jianshu.com/p/cdc3d03c144d 1. 下载 qq 轻聊版,可在百度搜索后下载 QQ7.9Light.exe 2. 去wine的官网(https://wiki.winehq.org/Ubuntu) 安装 wine . 提醒网页可以切换成中...

Canaan_
今天
0
0
PHP后台运行命令并管理运行程序

php后台运行命令并管理后台运行程序 class ProcessModel{ private $pid; private $command; private $resultToFile = ''; public function __construct($cl=false){......

colin_86
今天
1
0
数据结构与算法4

在此程序中,HighArray类中的find()方法用数据项的值作为参数传递,它的返回值决定是否找到此数据项。 insert()方法向数组下一个空位置放置一个新的数据项。一个名为nElems的字段跟踪记录着...

沉迷于编程的小菜菜
今天
1
1
fiddler安装和基本使用以及代理设置

项目需求 由于开发过程中客户端和服务器数据交互非常频繁,有时候服务端需要知道客户端调用接口传了哪些参数过来,这个时候就需要一个工具可以监听这些接口请求参数,已经接口的响应的数据,这种...

银装素裹
今天
0
0
Python分析《我不是药神》豆瓣评论

读取 Mongo 中的短评数据,进行中文分词 对分词结果取 Top50 生成词云 生成词云效果 看来网上关于 我不是药神 vs 达拉斯 的争论很热啊。关于词频统计就这些,代码中也会完成一些其它的分析任...

猫咪编程
今天
0
0
虚拟机怎么安装vmware tools

https://blog.csdn.net/tjcwt2011/article/details/72638977

AndyZhouX
昨天
1
0
There is no session with id[xxx]

参考网页 https://blog.csdn.net/caimengyuan/article/details/52526765 报错 2018-07-19 23:04:35,330 [http-nio-1008-exec-8] DEBUG [org.apache.shiro.web.servlet.SimpleCookie] - Found......

karma123
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部