java的anonymous inner class, 用的是lamda lifting技术来实现closure。即:
IX f(final int i){
  return new IX(){
     public int m(){
        return i;
     }
  };
}
这个anonymous class会被翻译成:
class IX$ implements IX{
  private final int i;
  public int m(){return i;}
  IX$(int i){this.i=i;}
}
IX f(int i){
  return new IX$(i);
}
如果i不是final, 也就是说,你可以改变i的值, 但是,lamda lifting的方法不可能在IX$对象中反映出这个i的值的变化。
IX f(int i){
  IX ret= new IX(){
     public int m(){
        return i;
     }
  };
  i++;
}
此处,虽然i++改变了i的值,但返回的IX对象中所记忆的那个i的值并没有变。这会造成混淆。其实,好的习惯是,尽量把一切都做成final的,如果实在需要改变,再变成mutable的。
所以,java只是在培养你的好习惯,不用觉得别扭。