java十大低级错误和常见注意点
Java十大低级错误
1、 不能用“==”比较两个字符串内容相等。
2、 对list做foreach循环时,循环代码中不能修改list的结构。
java foreach只能用于只读的情况.如果需要删除操作,请用迭代器或者直接遍历List.
3、 空指针异常。
4、 数组下标越界。
// 获取一个数组对象
String[] cIds = ContentService.queryByName(name);
if(null != cIds)
{
// 只是考虑到cids有可能为null的情况,但是cids完全有可能是个0长度的数组,因此cIds[0]有可能数组下标越界
5、 将字符串转换为数字时没有捕获NumberFormatException异常。
6、 对文件、IO、数据库等资源进行操作后没有及时、正确进行释放。
7、 循环体编码时不考虑性能,循环体中包含不需要的重复逻辑。
8、 数据类没有重载toString()方法。
9、 嵌套使用try-catch,或者try-catch后面没有必要的finally操作。
10、 equals操作时没有将常量放在equals操作符的左边。
java低级错误
- Calendar的错误使用
Calendar从星期日开始到星期六为一个周期,数字表示依次为:1,2,3……7;MONTH的表示是从数字0开始,所以月份应该是该数字+1。所以我们在使用的时候一定要仔细的阅读API文档,避免类似的陷阱。
- 序列化类的多版本问题
Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。当实现java.io.Serializable接口的实体(类)没有显式地定义serialVersionUID时,Java序列化机制会根据编译的class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,只有同一次编译生成的 class才会生成相同的serialVersionUID
---解决方法:可以在程序一生成一个
serialVersionUID属性,这样运行
就不会出错。
- 正确定义hashcode
- 解读
类A覆写了hashCode方法,并采用A的属性value来生成A的hashCode。使用HashSet作为集合对象,把类A的一个对象a加入到HashSet中后,如果对象a的属性value发生了变化,则a的hashCode()方法返回的值也就发生变化,则无法将对象a从HashSet中删除。
预防措施如下:
1、如果覆写了equals方法,必须同时覆写hashCode方法。
2、equals方法和hashCode方法应避免使用易变的属性,避免该对象的hashCode频繁变化。
3、当对象被加入到HashSet(或作为Key加入到HashMap)后,应该避免该对象的hashCode发生变化。
4.正确理解Java的浅clone和深clone
浅clone和深clone都是clone,它们本质区别是对象内部的成员属性(非原生类型属性,如int等)在clone时是否处理为引用。如果仍然保留为引用,则称为浅clone,反之称为深clone。浅clone方式得到clone对象即可,深clone方式在得到clone对象后,还需要对引用的成员属性进行“clone”处理。使用Vector等容器的clone方法一定要注意:对于不变属性可以直接拷贝,对于可变属性需要手动写方法实现深层拷贝防止引用调用。深拷贝要深到什么程度,答案就是一直深到你想要的程度,包括深到不能再深的程度。
- 为什么定义equals方法的同时也要定义hashCode方法
equals方法用于实现对象之间逻辑上是否相等的判断,而不是判断两个引用是否指向同一个对象,hashCode用于返回对象的哈希码(也有翻译成散列码的),逻辑上相等(equals比较相等)的两个不同对象它们返回的hashCode值肯定不相等。 Java规范中规定:如果两个对象根据equals(Object)方法是相等的,那么调用这两个对象中任一个对象的hashCode方法必须产生同样的整数结果,所以定义equals的同时一定要定义hashCode,并且要保证equals比较相等的对象,hashCode返回值也必须相同。
如果定义了equals方法,没有定义hashCode,两个对象的hashCode却不同,Map查找对象的时候会首先比较hashCode值,然后再使用equals比较,造成Map无法找到期望的对象。
- 大小写转换的正确处理
String提供有大小写转换方法:String.toUpperCase()和String.toLowerCase(),另外还有带Locale参数的大小写转换方法:String.toUpperCase(Locale locale)和String.toLowerCase(Locale locale)。 String.toUpperCase(Locale locale)和String.toLowerCase(Locale locale)之所以要带Locale参数,就是希望你指定使用的是哪种语言,不带参数的String.toUpperCase()和String.toLowerCase()使用的是系统缺省的语言,例如操作系统的当前语言。有些语言的大小写转换使用了较特殊的规则,甚至不是1:1的字符对应关系,也就是说转换前和转换后的字符串长度不一定相等。
---如果在Eclipse的run对话框中显示告诉VM我用的是Turkish,那最后输出的结果已经不是我预期的大写的I了,而是另外一个字符(İ)。
这个例子充分说明,大小写转换因语言环境的不同,转换结果可能并非如你所预期的。
如果大小写转换之后你是要用于字符串比较(这样的转换纯粹是为了比较的方便),也就是在我们的26个字母通常大小写转换预期内,则强烈建议你显示指定“英文”的Locale(Local.US)。
如果你的大小写转换就是希望遵循当前使用软件的国家语言大小写转换习惯,则使用不带参数的String.toUpperCase()和String.toLowerCase()更好一些,这样的代码反而能够适应不同的语言环境。
- 使用包装器对象带来的低效问题
解读
每个基本类型(primitive)都有相应的包装器(wrapper)对象:Integer、Long、Float、Double、Short、Byte、Character和Boolean,我们在使用时不要直接new Integer对象(这样的做法是低效的),而应该调用包装器对象的valueOf方法
为什么以上代码是低效的,而要使用Integer result = Integer.valueOf(-1)或者Integer result = -1来代替?我们来看看JDK的Integer.valueOf方法实现
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
可以看到内存中已经缓存有-128到127这个区间的256个Integer对象,如果方法传入的i值介于这个范围就不用再new Integer对象了,省去了运行时间,也节省了内存资源。另外的几个包装器对象( Long、Short、Byte、Character和Boolean )类似。
- 对于Map元素的遍历使用entrySet还是KeySet?
JDK实现的数据结构中常用的Map有两类:HashMap和TreeMap。keySet和entrySet在Map元素数较少时(小于10000)在查询速度上的区别不大,它们对于程序性能的影响可以忽略不计。但在元素较多时(大于100000)时entrySet的速度要明显快于keySet,尤其是TreeMap更明显。
- 对InputStream.skip()返回值的处理(隐藏的异常)
java.io.InputStream.skip(long n):跳过和放弃此输入流中的 n 个数据字节,返回的是跳过的实际字节数。如果skip方法的返回值小于要跳过得字节数,则说明有异常发生,此时需要对异常情况进行处理。
需要比较skip的返回值和输入参数,如果两者不相等时,需做特殊处理。
两者不相等的情况可能的原因有:
1)在跳过 n 个字节之前已到达文件的末尾;
2)输入参数为负;
- 正确理解String/StringBuffer/StringBuilder的区别
StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。
StringBuilder提供一个与StringBuffer兼容的API,该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
11.
- Java中流的操作,不要使用匿名流对象,以免出现异常,没有句柄,无法关闭
例子:
try
{
File file = new File("test.exe");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
//之后只关闭了一个流bis,匿名流new FileInputStream(file)没有关闭
........
}
改写之后:
try
{
File file = new File("test.exe");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
//之后关闭两个流fis和bis
........
}
这个效率相对低点
m.keySet().iterator()
以后最好用下面这个
jmap.entrySet().iterator()
java十大低级错误和常见注意点的更多相关文章
- 1000多个项目中的十大JavaScript错误以及如何避免
通过统计数据库中的1000多个项目,我们发现在 JavaScript 中最常出现的错误有10个.下面会向大家介绍这些错误发生的原因以及如何防止. 对于这些错误发生的次数,我们是通过收集的数据统计得出的 ...
- MySQL数据库“十宗罪”【十大经典错误案例】
原文作者:张甦 来源:http://blog.51cto.com/sumongodb 今天就给大家列举 MySQL 数据库中,最经典的十大错误案例,并附有处理问题的解决思路和方法,希望能给刚入行,或数 ...
- java 十大经典排序算法
十大排序算法可以说是每个程序员都必须得掌握的了,花了一天的时间把代码实现且整理了一下,为了方便大家学习,我把它整理成一篇文章,每种算法会有简单的算法思想描述,为了方便大家理解,我还找来了动图演示:这还 ...
- 【转】Java十大常用框架介绍(spring系+dubbo+RabbitMQ+Ehcache+redis)
一.SpringMVC Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动 ...
- JAVA十大经典排序算法最强总结(含JAVA代码实现)
十大经典排序算法最强总结(含JAVA代码实现) 最近几天在研究排序算法,看了很多博客,发现网上有的文章中对排序算法解释的并不是很透彻,而且有很多代码都是错误的,例如有的文章中在“桶排序”算法中对每 ...
- MySQL数据库“十宗罪”(十大经典错误案例)
Top 1: Too many connections(连接数过多,导致连接不上数据库,业务无法正常进行) 问题还原 1 2 3 4 5 6 mysql> show variables lik ...
- java十大排序
0.1 算法分类 十种常见排序算法可以分为两大类: 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序. 非比较类排序:不通过比较来决 ...
- JAVA十大经典排序算法最强总结(含JAVA代码实现)
0.排序算法说明 0.1 排序的定义 对一序列对象根据某个关键字进行排序. 0.2 术语说明 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面: 不稳定:如果a原本在b的前面,而a=b,排 ...
- Java 十大排序算法
目录: 1.冒泡排序(Bubble Sort) 2.选择排序(Selection Sort) 3.插入排序(Insertion Sort) 4.希尔排序(Shell Sort) 5.归并排序(Merg ...
随机推荐
- 带你走进EJB--将EJB发布为Webservice(4)
接下来的我们将会自定义一个对象,然后看看EJB是如何对复杂的参数发布成WebService的. 代码如下:在第一个版本的基础之上加上增加用户的方法,参数为User. package com.tgb.e ...
- poj 1664 放苹果(递推)
题目链接:http://poj.org/problem? id=1664 放苹果 Time Limit: 1000MS Memory Limit: 10000K Total Submissions ...
- 算法笔记_201:第三届蓝桥杯软件类决赛真题(Java本科)
目录 1 数量周期 2 提取子串 3 源码变换 4 古代赌局 5 火柴游戏 前言:以下代码仅供参考,若有错误欢迎指正哦~ 1 数量周期 [结果填空](满分9分) 复杂现象背后的推动力,可能是极其简 ...
- Docker 命令导图
- Java多线程之线程阻塞原语LockSupport的使用
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6558597.html 看名字就知道了,LockSupport——提供对加锁机制的支持. 它是提供线程阻塞的原 ...
- VTK中获取STL模型点的坐标以及对其进行变换
VTK是一个基于面向对象的开源三维绘图软件包,和其它的的三维绘图引擎如OSG.OGRE不同之处在于,VTK可视化对象主要是各种数据,更加注重对数据分析处理后的可视化,可视化的内容是人们无法直接感受到的 ...
- excel单元格对齐方式
需要注意下面几点: 1.强制换行,ctrl+回车 2.快速设置缩进,当我们选择需要调整缩进的单元格之后,点击格式---单元格格式---选择水平对齐方式之后,可以选择缩进. 3.注意跨行居中功能,尤其是 ...
- 二维码Data Matrix简单介绍及在VS2010中的编译
Data Matrix 二维条码原名Datacode,由美国国际资料公司(International Data Matrix, 简称ID Matrix)于1989年发明.Data-Matrix二维条码 ...
- shell脚本把一些请求量非常高的ip给拒绝掉
需求: 根据web服务器上的访问日志,把一些请求量非常高的ip给拒绝掉!并且每隔半小时把不再发起请求或者请求量很小的ip给解封. 假设: 1. 一分钟内请求量高于100次的IP视为不正常请求 ...
- 用yum下载rpm包(不安装)到制定目录
用yum下载rpm包(不安装)到制定目录用yum下载rpm包 www.pcjsh.com 1.安装yum-downloadonly # yum install yum-downloadonly -y ...