本文主要是介绍Java中令人发狂的程序语言的特性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Java的Integer cache
- Integer foo = 1000;
- Integer bar = 1000;
- foo <= bar; // true
- foo >= bar; // true
- foo == bar; // false
- //然后,如果你的 foo 和 bar 的值在 127 和 -128 之间(包括)
- //那么,其行为则改变了:
- Integer foo = 42;
- Integer bar = 42;
- foo <= bar; // true
- foo >= bar; // true
- foo == bar; // true
为什么会这样呢?你需要了解一下Java Interger Cache,下面是相关的程序,注意其中的注释
- /**
- * Returns a <tt>Integer</tt> instance representing the specified
- * <tt>int</tt> value.
- * If a new <tt>Integer</tt> instance is not required, this method
- * should generally be used in preference to the constructor
- * <a href="mailto:{@link">{@link</a> #Integer(int)}, as this method is likely to yield
- * significantly better space and time performance by caching
- * frequently requested values.
- *
- * @param i an <code>int</code> value.
- * @return a <tt>Integer</tt> instance representing <tt>i</tt>.
- * @since 1.5
- */
- public static Integer valueOf(int i) {
- if(i >= -128 && i <= IntegerCache.high)
- return IntegerCache.cache[i + 128];
- else
- return new Integer(i);
- }
Java的异常返回
请看下面这段程序,你觉得其返回true还是false?
- try {
- return true;
- } finally {
- return false;
- }
在 javascript 和python下,其行为和Java的是一样的。
错误1:长整数赋值问题
系统有一个功能要产生邀请码,客户通过邀请码进行注册,但是邀请码要有过期时间,希望60天后过期,过期时间采用毫秒数:
- long EXPIRED_DATE = 60 * 24 * 60 * 60 * 1000;
可是,测试人员告诉我,邀请码10天不到就过期了,我看了代码,百思不解,最后跟踪了代码,才发现
并不会自动转化为long,而是一个int,10天的毫秒数就超过了int的最大值了,因此10天不到就过期了!
这儿犯下的错误是其实对 “整数字面值赋值时默认为int型”这个基础Java知识的忽视造成的.如果要让JVM将字面数字当成long,则必须在字面数字后显示加L标识,所以这个BUG是这样解决的:
- long EXPIRED_DATE = 60 * 24 * 60 * 60 * 1000L;
错误2:数值越界的问题
我写的一个模块允许开发者注册插件,为了控制插件执行的先后顺序,因此我写了一个Orderable接口,插件实现该接口以决定执行的先后顺序(orderNo越小越先执行):
- public interface Orderable {
- /**
- * 排序号,越小越在前面
- */
- int getOrdreNo();
- }
然后写了一个Comparator,以便可以通过java.util.Collections的
- sort(List<T> list,Comparator<? super T> c)
对插件List进行排序。Comparator是这样写的:
- public class OrderableComparator implements Comparator {
- private static OrderableComparator intance = new OrderableComparator();
- private OrderableComparator() {
- }
- public int compare(Object obj1, Object obj2) {
- int order1 = Integer.MAX_VALUE;
- int order2 = Integer.MAX_VALUE;
- if (obj1 instanceof Orderable) {
- order1 = ((Orderable) obj1).getOrdreNo();
- }
- if (obj2 instanceof Orderable) {
- order2 = ((Orderable) obj2).getOrdreNo();
- }
- return order1 - order2;//① 大家注意这儿是出鬼的地方!!!
- }
- public static OrderableComparator getIntance() {
- return intance;
- }
- }
但是一个兄弟咆哮地告诉我,它的插件的getOrderNo()已经设置为Integer.MIN_VALUE,但是却在最后一位执行!!!
跟踪了代码,才发现是对数值越界问题的忽视而造成了这个低级错误,下面具体分析一下,如Plugin1的getOrdreNo()为Integer.MIN_VALUE,而Plugin2的getOrdreNo()为1,可是大家想想下面的计算值是多少呢?
- Integer.MIN_VALUE - 1
是2147483647!!
找到问题后改起来是不费工夫的:
- public int compare(Object obj1, Object obj2) {
- int order1 = Integer.MAX_VALUE;
- int order2 = Integer.MAX_VALUE;
- if (obj1 instanceof Orderable) {
- order1 = ((Orderable) obj1).getOrdreNo();
- }
- if (obj2 instanceof Orderable) {
- order2 = ((Orderable) obj2).getOrdreNo();
- }
- if(order1 > order2){
- return 1;
- }else if(order1 < order2){
- return -1;
- }else{
- return 0;
- }
- }
这篇关于Java中令人发狂的程序语言的特性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!