3. 它们都是二维数组!
  class Test {
  int[][] a()  { return new int[0][]; }
  int[] b() [] { return new int[0][]; }
  int c() [][] { return new int[0][]; }
  }
  是的,没错。也许你无法马上说出上述方法的返回类型是什么,但它们的确都是一样的!同样的还有下面这段代码:
  class Test {
  int[][] a = ;
  int[] b[] = ;
  int c[][] = ;
  }
  你是不是觉得这有点疯狂?相像一下如果再用上JSR-308/Java 8中的类型注解吧。各种写法数不胜数。
@Target(ElementType.TYPE_USE)
@interface Crazy {}
class Test {
@Crazy int[][]  a1 = ;
int @Crazy [][] a2 = ;
int[] @Crazy [] a3 = ;
@Crazy int[] b1[]  = ;
int @Crazy [] b2[] = ;
int[] b3 @Crazy [] = ;
@Crazy int c1[][]  = ;
int c2 @Crazy [][] = ;
int c3[] @Crazy [] = ;
}
  类型注解。神秘之极,强大之极。
  或者这么说:
  亲爱的同事,提交完这段代码下月我要休假了:
  这些写法到底有什么用,这个留给你自己慢慢探索吧。
  4. 你根本不懂条件表达式
  那么,你以为条件表达式你很了解了吗?我告诉你吧,你压根不懂。很多人都认为下面两段代码是一样的:
  Object o1 = true ? new Integer(1) : new Double(2.0);
  它和下面这个是一样的吧?
  Object o2;
  if (true)
  o2 = new Integer(1);
  else
  o2 = new Double(2.0);
  不是的。我们来测试下。
  System.out.println(o1);
  System.out.println(o2);
  这段代码会输出:
  1.0
  1
  没错,条件操作符在"必要"的时候会进行数值类型的提升,这个“必要”得加上一个重重的引号。你能想到下面这段程序居然会抛出一个空指针异常吗?
  Integer i = new Integer(1);
  if (i.equals(1))
  i = null;
  Double d = new Double(2.0);
  Object o = true ? i : d; // NullPointerException!
  System.out.println(o);
  想了解更多请参考这里。
  5. 你也不懂复合赋值操作符
  很奇怪吧?我们再来看下这两段代码:
  i += j;
  i = i + j;
  显然他们都是一样的嘛。不过,其实不然。Java语言规范中是这么说的:
  E1 op= E2形式的复合赋值表达式等价于E = (T)((E1) op (E2)),这里的T的类型是E1,E1仅会进行一次求值。
  这太奇妙了。我想引用一下Peter Lawre在Stack Overflow上面的一个回答:
  这种类型的类型转换通过*=或者/=可以很容易地说明:
  byte b = 10;
  b *= 5.7;
  System.out.println(b); // prints 57
  或者
  byte b = 100;
  b /= 2.5;
  System.out.println(b); // prints 40
  或者
  char ch = '0';
  ch *= 1.1;
  System.out.println(ch); // prints '4'
  又或者:
  char ch = 'A';
  ch *= 1.5;
  System.out.println(ch); // prints 'a'
  那么这么做到底有什么用?你可以在你的程序里试一下char类型的类型转换和乘法操作。因为你懂的,这够装逼。