对float和double使用==比较

//错误的写法:
for (float f = 10f; f!=0; f-=0.1) {   System.out.println(f);
}
/**上面的浮点数递减只会无限接近0而不会等于0, 这样会导致上面的for进入死循环. 通常绝不要对float和double使用==操作. 而采用大于和小于操作. 如果java编译器能针对这种情况给出警告. 或者在java语言规范中不支持浮点数类型的==操作就最好了。**///正确的写法:
for (float f = 10f; f>0; f-=0.1) {   System.out.println(f);
}

用浮点数来保存金额

//错误的写法:
float total = 0.0f;
for (OrderLine line : lines) {   total += line.price * line.count;
}
double a = 1.14 * 75; // 85.5 将表示为 85.4999...
System.out.println(Math.round(a)); // 输出值为85
BigDecimal d = new BigDecimal(1.14); //造成精度丢失/**这个也是一个老生常谈的错误. 比如计算100笔订单, 每笔0.3元, 最终的计算结果是29.9999971. 如果将float类型改为double类型, 得到的结果将是30.000001192092896. 出现这种情况的原因是, 人类和计算的计数方式不同. 人类采用的是十进制, 而计算机是二进制.二进制对于计算机来说非常好使, 但是对于涉及到精确计算的场景就会带来误差. 比如银行金融中的应用。
因此绝不要用浮点类型来保存money数据. 采用浮点数得到的计算结果是不精确的. 即使与int类型做乘法运算也会产生一个不精确的结果.那是因为在用二进制存储一个浮点数时已经出现了精度丢失. 最好的做法就是用一个string或者固定点数来表示. 为了精确, 这种表示方式需要指定相应的精度值.
BigDecimal就满足了上面所说的需求. 如果在计算的过程中精度的丢失超出了给定的范围, 将抛出runtime exception.**///正确的写法:
BigDecimal total = BigDecimal.ZERO;
for (OrderLine line : lines) {   BigDecimal price = new BigDecimal(line.price);   BigDecimal count = new BigDecimal(line.count);   total = total.add(price.multiply(count)); // BigDecimal is immutable!
}
total = total.setScale(2, RoundingMode.HALF_UP);
BigDecimal a = (new BigDecimal("1.14")).multiply(new BigDecimal(75)); // 85.5 exact
a = a.setScale(0, RoundingMode.HALF_UP); // 86
System.out.println(a); // correct output: 86
BigDecimal a = new BigDecimal("1.14");

字符串连接的错误写法

//错误的写法:
String s = "";
for (Person p : persons) {  s += ", " + p.getName();
}
s = s.substring(2); //remove first comma//正确的写法:
StringBuilder sb = new StringBuilder(persons.size() * 16); // well estimated buffer
for (Person p : persons) {if (sb.length() > 0) sb.append(", ");sb.append(p.getName);
}

StringBuffer 的错误使用

//错误的写法:
StringBuffer sb = new StringBuffer();
sb.append("Name: ");
sb.append(name + '\n');
sb.append("!");
...
String s = sb.toString();
/**问题在第三行,append char比String性能要好,另外就是初始化StringBuffer没有指定size,导致中间append时可能重新调整内部数组大小。如果是JDK1.5最好用StringBuilder取代StringBuffer,除非有线程安全的要求。还有一种方式就是可以直接连接字符串。缺点就是无法初始化时指定长度。**///正确的写法:
StringBuilder sb = new StringBuilder(100);
sb.append("Name: ");
sb.append(name);
sb.append("\n!");
String s = sb.toString();
//或者这样写:
String s = "Name: " + name + "\n!";

字符串的比较

//错误的写法:
if (name.compareTo("John") == 0) ...
if (name == "John") ...
if (name.equals("John")) ...
if ("".equals(name)) ...//正确的写法:
if ("John".equals(name)) ...
if (name.length() == 0) ...
if (name.isEmpty()) ...

 数字转换成字符串

//错误的写法:
"" + set.size()
new Integer(set.size()).toString()//正确的写法:
String.valueOf(set.size())

利用不可变对象(Immutable)

//错误的写法:
zero = new Integer(0);
return Boolean.valueOf("true");//正确的写法:
zero = Integer.valueOf(0);
return Boolean.TRUE;

请使用XML解析器

//错误的写法:
int start = xml.indexOf("<name>") + "<name>".length();
int end = xml.indexOf("</name>");
String name = xml.substring(start, end);//正确的写法:
SAXBuilder builder = new SAXBuilder(false);
Document doc = doc = builder.build(new StringReader(xml));
String name = doc.getRootElement().getChild("name").getText();

请使用JDom组装XML

//错误的写法:
String name = ...
String attribute = ...
String xml = "<root>" +"<name att=\""+ attribute +"\">"+ name +"</name>" +"</root>";
//正确的写法:
Element root = new Element("root");
root.setAttribute("att", attribute);
root.setText(name);
Document doc = new Documet();
doc.setRootElement(root);
XmlOutputter out = new XmlOutputter(Format.getPrettyFormat());
String xml = out.outputString(root);

 未指定字符编码

//错误的写法:
Reader r = new FileReader(file);
Writer w = new FileWriter(file);
Reader r = new InputStreamReader(inputStream);
Writer w = new OutputStreamWriter(outputStream);
String s = new String(byteArray); // byteArray is a byte[]
byte[] a = string.getBytes();
//这样的代码主要不具有跨平台可移植性。因为不同的平台可能使用的是不同的默认字符编码。//正确的写法:
Reader r = new InputStreamReader(new FileInputStream(file), "ISO-8859-1");
Writer w = new OutputStreamWriter(new FileOutputStream(file), "ISO-8859-1");
Reader r = new InputStreamReader(inputStream, "UTF-8");
Writer w = new OutputStreamWriter(outputStream, "UTF-8");
String s = new String(byteArray, "ASCII");
byte[] a = string.getBytes("ASCII");

未对数据流进行缓存

//错误的写法:
InputStream in = new FileInputStream(file);
int b;
while ((b = in.read()) != -1) {
...
}
/**上面的代码是一个byte一个byte的读取,导致频繁的本地JNI文件系统访问,非常低效,因为调用本地方法是非常耗时的。最好用BufferedInputStream包装一下。曾经做过一个测试,从/dev/zero下读取1MB,大概花了1s,而用BufferedInputStream包装之后只需要60ms,性能提高了94%! 这个也适用于output stream操作以及socket操作。**///正确的写法:
InputStream in = new BufferedInputStream(new FileInputStream(file));

 不指定超时时间

//错误的代码:
Socket socket = ...
socket.connect(remote);
InputStream in = socket.getInputStream();
int i = in.read();
/**这种情况在工作中已经碰到不止一次了。个人经验一般超时不要超过20s。这里有一个问题,connect可以指定超时时间,但是read无法指定超时时间。但是可以设置阻塞(block)时间。**///正确的写法:
Socket socket = ...
socket.connect(remote, 20000); // fail after 20s
InputStream in = socket.getInputStream();
socket.setSoTimeout(15000);
int i = in.read();
/**另外,文件的读取(FileInputStream, FileChannel, FileDescriptor, File)没法指定超时时间, 而且IO操作均涉及到本地方法调用, 这个更操作了JVM的控制范围,在分布式文件系统中,对IO的操作内部实际上是网络调用。一般情况下操作60s的操作都可以认为已经超时了。为了解决这些问题,一般采用缓存和异步/消息队列处理。**/

捕获所有的异常

//错误的写法:
Query q = ...
Person p;
try {   p = (Person) q.getSingleResult();
} catch(Exception e) {   p = null;
}
/**这是EJB3的一个查询操作,可能出现异常的原因是:结果不唯一;没有结果;数据库无法访问,而捕获所有的异常,设置为null将掩盖各种异常情况。**///正确的写法:
Query q = ...
Person p;
try {   p = (Person) q.getSingleResult();
} catch(NoResultException e) {   p = null;
}

重复包装RuntimeException

//错误的写法:
try {   doStuff();
} catch(Exception e) {   throw new RuntimeException(e);
}//正确的写法:
try {   doStuff();
} catch(RuntimeException e) {   throw e;
} catch(Exception e) {   throw new RuntimeException(e.getMessage(), e);
}
try {   doStuff();
} catch(IOException e) {   throw new RuntimeException(e.getMessage(), e);
} catch(NamingException e) {   throw new RuntimeException(e.getMessage(), e);
}

异常处理不彻底

//错误的写法:
try {   is = new FileInputStream(inFile);   os = new FileOutputStream(outFile);
} finally {   try {   is.close();   os.close();   } catch(IOException e) {   /* we can't do anything */   }
}//is可能close失败, 导致os没有close
//正确的写法:
try {   is = new FileInputStream(inFile);   os = new FileOutputStream(outFile);
} finally {   try { if (is != null) is.close(); } catch(IOException e) {/* we can't do anything */}   try { if (os != null) os.close(); } catch(IOException e) {/* we can't do anything */}
}

不必要的初始化

//错误的写法:
public class B {   private int count = 0;   private String name = null;   private boolean important = false;
}
//这里的变量会在初始化时使用默认值:0, null, false, 因此上面的写法有些多此一举。//正确的写法:
public class B {   private int count;   private String name;   private boolean important;
}

最好用静态final定义Log变量

这样做的好处有三:

  • 可以保证线程安全
  • 静态或非静态代码都可用
  • 不会影响对象序列化
private static final Log log = LogFactory.getLog(MyClass.class);

 选择错误的类加载器

//错误的代码:
Class clazz = Class.forName(name);
Class clazz = getClass().getClassLoader().loadClass(name);
/**这里本意是希望用当前类来加载希望的对象, 但是这里的getClass()可能抛出异常, 特别在一些受管理的环境中, 比如应用服务器, web容器, Java WebStart环境中, 最好的做法是使用当前应用上下文的类加载器来加载。**///正确的写法:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) cl = MyClass.class.getClassLoader(); // fallback
Class clazz = cl.loadClass(name);

HashMap size陷阱

//错误的写法:
Map map = new HashMap(collection.size());
for (Object o : collection) {  map.put(o.key, o.value);
}
/**这里可以参考guava的Maps.newHashMapWithExpectedSize的实现. 用户的本意是希望给HashMap设置初始值, 避免扩容(resize)的开销. 但是没有考虑当添加的元素数量达到HashMap容量的75%时将出现resize。**///正确的写法:
Map map = new HashMap(1 + (int) (collection.size() / 0.75));

未完待续。。。。

Java代码常见错误写法相关推荐

  1. 编写HTML代码常见错误以及解决方法?

    编写HTML代码常见错误以及解决方法? 参考文章: (1)编写HTML代码常见错误以及解决方法? (2)https://www.cnblogs.com/sqyss/p/11105221.html 备忘 ...

  2. JAVA编程常见错误集锦

    本文转自:http://hi.baidu.com/zzcc_8/blog/item/23f83a43dda0611f72f05d02.html 项目中遇到的错误(c9bcf64c) sql错误 找不到 ...

  3. 50 个 Java 开发常见错误及规避技巧 (Part 2)

    转载至:https://www.oschina.net/translate/50-common-java-errors-and-how-to-avoid-them-part-2 编译器错误 编译器错误 ...

  4. PAT提交JAVA代码编译错误

    这是我在PAT在提交java代码时的一种编译错误,如下图所示 这种编译错误主要是由于在提交Java代码d的过程中格式出现错误,只需要在class后面的类名改成"Main"就可以了, ...

  5. java cause_java常见错误Cause java.sql.SQLSyntaxErrorException Table ‘m

    java常见错误Cause java.sql.SQLSyntaxErrorException Table 'm java常见错误:Cause: java.sql.SQLSyntaxErrorExcep ...

  6. java代码走查常见错误_FindBugs常见错误描述和解决方法

    (一)[DLS_DEAD_LOCAL_STORE] 描述: Dead store to 未使用的局部变量 解决方法:局部变量定义后未使用:实例化对象后又重新对该对象赋值 (二) [ST_WRITE_T ...

  7. java实验常见错误_java 实验4 异常

    异常(实际使用直接try-catch) 1.常见系统异常 异常 异常的解释 ClassNotFoundException 未找到要装载的类 ArrayIndexOutOfBoundsException ...

  8. java实验常见错误_求高手点拨一个Java SWING的IM系统实验的错误解决方案。

    高手,您好: 小弟遇到的代码场景为: 制作了一个Java SWING技术结合Socket技术实现的IM通信实验. 通信为双向全双工通信,通信方分为S端和C端. 下面,小弟贴出小弟的全部实验源代码,请高 ...

  9. 按键精灵调试三天,气到吐血!!快速开发脚本代码常见错误!绝对干货!

    来源:按键学院   [按键精灵] 还记不记得,那些天,急着交脚本的时候出bug了.通宵了三天三夜,调试出错.逻辑检查了一边又一边,万行代码反反复复翻来覆去推敲了无数遍.结果-- 不要告诉我是中英文符号 ...

  10. java栈代码执行_这段实现栈的java代码执行错误..

    每次执行到s.push(item)这里就错了..刚开始学java并不是很懂.. package test; import java.util.Scanner; public class FixedCa ...

最新文章

  1. IBatis.Net学习笔记六--再谈查询
  2. pybind11向C++ dll 传递数组 图像
  3. 使用GLSL实现雾化的效果
  4. practical rendering and computation with dx11 ebook
  5. jenkins+maven+ansible实现测试环境完全自动发布
  6. Angular里的特殊字符ɵ和ABAP变量名里的特殊字符*
  7. oracle存储返回sql查询,如何做才能使record类型和table类型存储查询语句返回的多条记录?...
  8. node ajax validator,node/express 4:在ajax post上使用express-validator显示错误
  9. springboot获取客户端发来的数据
  10. java数组的定义(菜鸟教程)
  11. 空硬盘恢复linux,linux使用foremost恢复文件,硬盘恢复
  12. chrome 开启HEVC硬件解码
  13. 如何将html转换成url,HTML URL
  14. 老韩思考:一个卖豆腐的能转行IT吗? 你的卖点在哪里?
  15. 易语言制作的QQ聊天中常用的GIF图片【带源码下载】
  16. 虚拟机Linux共享主机Windows文件夹
  17. 【概率期望】【NOIP模拟】切题
  18. 理解elasticsearch
  19. 祭奠信任Nokia的那些日子
  20. 【二】、什么是抽象数据类型

热门文章

  1. 高效算法:竞赛、应试与提高必修128例
  2. 使用stylebook制作精美界面的方法(firemonkey)
  3. 实用网站汇总(不定期更新)
  4. centos设置静态IP地址
  5. con和com开头单词规律_英语单词速记小技巧
  6. php match_PHP8.0新功能之Match表达式的使用
  7. java 对数运算_使用java计算log值
  8. 多功能数字时钟(VHDL)
  9. FPGA数字时钟计数器
  10. 动态规划法(入门)——最大正方形、最大长方形