问题:奇数性
代码:
public class Odd { /** * 奇数性 * @authorLiangGzone */ public static void main(String[] args) { System.out.println("1是奇数吗?"+isOdd(1)); System.out.println("2是奇数吗?"+isOdd(2)); System.out.println("-1是奇数吗?"+isOdd(-1)); } public static boolean isOdd(int i){ return i % 2 == 1; } }
分析:这是Java对取余操作符(%)的定义所产生的。isOdd方法对于对所有负奇数的判断都会失败。在任何负整数上调用该方法都回返回false,不管该整数是偶数还是奇数。
建议:无论你何时使用到了取余操作符,都要考虑到操作数和结果的符号。
解决:
方案一:
public static boolean isOdd(int i){ returni % 2 != 0; }
方案二:
public static boolean isOdd2(inti){ return(i & 1) != 0; }
问题:长整除
代码:
/** *长整除 * @authorLiangGzone */ public class LongDivision { publicstatic void main(String[] args) { finallong MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000; finallong MILLIS_PER_DAY = 24 * 60 * 60 * 1000; System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY); } }
分析:当两个int数值相乘时,将得到另一个int数值。因此最后的结果是int数值,从而导致溢出。
建议:当在操作很大的数字时,千万要提防溢出。
解决:
方案:强制表达式中的所有后续计算都用long运算来完成
public class LongDivision2 { publicstatic void main(String[] args) { finallong MICROS_PER_DAY = 24L * 60 * 60 * 1000 * 1000; finallong MILLIS_PER_DAY = 24L * 60 * 60 * 1000; System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY); } }
问题:找零时刻
代码:
/** *找零时刻 * @authorLiangGzone */ public class Change { publicstatic void main(String[] args) { System.out.println(2.0-1.1); } }
分析:并不是所有的小数都可以用二进制浮点数精确表示。
建议:在需要精确答案的地方,要避免使用float和double。对于货币计算,要使用int、long、BigDecimal。一定要用BigDecimal(String)构造器,而千万不要用BigDecimal(double)。后一个构造器将用它的参数的精确值来创建一个实例。
解决:
方案一:JDK5.0或更新版本,可以使用printf方法
public class Change2 { publicstatic void main(String[] args) { System.out.printf("%.2f",2.0-1.1); } }方案二:使用BigDecimal类
public class Change3 { publicstatic void main(String[] args) { BigDecimalbigNum1 = newBigDecimal("2.0"); BigDecimalbigNum2 = newBigDecimal("1.1"); System.out.println(bigNum1.subtract(bigNum2)); } }
问题:初级问题
代码:
/** * 初级问题 * @authorLiangGzone */ public class Elementary { publicstatic void main(String[] args) { System.out.println(12345+5432l); } }
分析:“5432l”中的“l”是小写的“L”。
建议:在long类型常量中,一定要用大写的L,千万不要使用小写的l。类似地,要避免使用单个l字母作为变量名。
解决:
方案:
public class Elementary { publicstatic void main(String[] args) { System.out.println(12345+5432L); } }
问题:多重转型
代码:
/** *多重转型 * @authorLiangGzone */ public class Multicast { publicstatic void main(String[] args) { System.out.println((int)(char)(byte)-1); } }分析:如果最初的数值类型是有符号的,就执行符号扩展。如果是char,那么不管它将要被转换成什么类型,都执行零扩展。
问题:Dos Equis
代码:
/** * DosEquis * @authorLiangGzone */ public class DosEquis { publicstatic void main(String[] args) { charx = 'X'; inti = 0; System.out.println(true?x:0); System.out.println(false?i:x); } }
建议:最好在表达式中使用类型相同的第2个和第3个操作数。
链接:
Java陷阱(二)