java中的那些坑(一)

下面的坑有些来自别人的技术博客,有些事以前自己遇到的坑,持续补充。。。


坑1:三目运算符

首先我们看一下这道题:char x = 'x';System.out.println(true?120:x);

我们的第一反应结果不就是120吗,但是我们实际运行一下,结果是x。是不是有种诧异的感觉,是不是觉得被带沟里去了?不知道大家感觉如何,反正我看到这个结果都惊呆了。对于三目运算符中的两个结果,如果一个是常量,一个是类型T的变量,则常量会被转型为类型T,这个据说是java编程规范中规定的,反正我是没看过,就此记住一条。所以常量120被转型为char,对应于x(小写)。

扩展1:

  1. int a=5;  
  2. System.out.println("a="+((a<5)?10.9:9));  

输出:9.0。因为三目运算符中有一个10.9,java会根据运算符的精度类型进行自动类型转换。因此9会变为9.0

扩展2:

  1. char x='x';  
  2. int i=10;  
  3. System.out.println(false?i:x);  
  4. System.out.println(false?100:x);  

而这段代码的输出是

120

x

对于第一行输出,与上个例子相同,x被提升了类型,变为int

而对于第二行,由于100是一个常量。若三目运算符中的两个表达式有一个是常量表达式,另一个是类型T的表达式,且常量表达式可以被T表示,则输出结果是T类型。因此输出是字符x

坑2:{}真是可有可无吗?

     先看题目:

       for(int i=0;i<10;i++)

          Integer k=new Integer(i);

           System.out.println("hello world");

请问结果如何?

我第一反应没有认真看,然后觉得直接输出hello world.但是实际上呢,根本编译不过去。

平时我的感觉就是,如果for中只有一行语句,那就不加{}了,免得看得那么多,所以印象中,对于一行的循环体,觉得{}是可有可无的。然而,事实是,java中的局部变量应该是在一个代码块中,也可以理解为是在{}中。for可以不加{},但是只限于执行语句,不包括局部变量声明的语句,而在本例中,就出现了局部变量重复定义的错误,改正的办法是加上{}。可见,{}还真不是可有可无的,怪不得刚开始学编程时候老是说用不用带带着呢,还是有道理的呀


坑3:除0

  1. System.out.println(1.0d / 0);  
  2. System.out.println(0.0d / 0);  
  3. System.out.println(1 / 0);  
  4. System.out.println(0 / 0);  

输出:

Infinity

NaN

java.lang.ArithmeticException: / by zero

at test.ww.Test.main(Test.java:27)

java.lang.ArithmeticException: / by zero

at test.ww.Test.main(Test.java:32)

 

原因:

因为 IEEE 754 有规定无穷大是怎么表示的,因此被除数不为 0,除数是 0 的话计算结果是正无穷或者是负无穷,如果被除数和除数都是 0 的话,那么计算结果是 NaN

 

整数不在是 IEEE 754 规定的,也没有无穷大的表示,因此只能抛出异常了


坑4: Arrays.asList?可变长参数?

int
[] arr = new int[]{1,2,3};  
System.out.println(Arrays.asList(arr).contains(1));  

输出什么?

大多数人的回答肯定是true,显而易见么。。但它输出的却是false,为什么,哪里出错了么?

分解一下表达式,先调用Arrays.asList(arr),通过遍历或者debug你会发现里面的元素个数为1,这又是什么原因呢,查看一下API或者源代码,发现它声明为List Arrays.asList(T... args),难道是可变长参数有问题?

做一个测试:

  1. public static void main(String[] args) {  
  2.   
  3.        int[] arr = new int[]{123 };  
  4.        test1(arr);  
  5.   
  6.    }  
  7.   
  8.    private static void test1(Object... values) {  
  9.        System.out.println(values.length);  
  10.    }  


输出

1

把int数组改为Integer数组后,输出

3

 

看来是基本类型的数组被当作了一个对象,而对象类型的数组的每个元素才能分别作为可变长参数方法的参数。

 


你可能感兴趣的:(Java)