为什么匿名内部类参数必须为final类型

1)  从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形式参数定义处或者方法体处),因而访问方法中的局部变量(形式参数或局部变量)是天经地义的.是很自然的

2)  为什么JAVA中要加上一条限制:只能访问final型的局部变量?

3)  JAVA语言的编译程序的设计者当然全实现:局部内部类能访问方法中的所有的局部变量(因为:从理论上这是很自然的要求),但是:编译技术是无法实现的或代价极高.

4)  困难在何处?到底难在哪儿? 

     局部变量的生命周期与局部内部类的对象的生命周期的不一致性!

5)  设方法f被调用,从而在它的调用栈中生成了变量i,此时产生了一个局部内部类对象inner_object,它访问了该局部变量i .当方法f()运行结束后,局部变量i就已死亡了,不存在了.但:局部内部类对象inner_object还可能   一直存在(只能没有人再引用该对象时,它才会死亡),它不会随着方法f()运行结束死亡.这时:出现了一个"荒唐"结果:局部内部类对象 inner_object要访问一个已不存在的局部变量i!

6)  如何才能实现?当变量是final时,通过将final局部变量"复制"一份,复制品直接作为局部内部中的数据成员.这样:当局部内部类访问局部变量 时,其实真正访问的是这个局部变量的"复制品"(即:这个复制品就代表了那个局部变量).因此:当运行栈中的真正的局部变量死亡时,局部内部类对象仍可以 访问局部变量(其实访问的是"复制品"),给人的感觉:好像是局部变量的"生命期"延长了.

那么:核心的问题是:怎么才能使得:访问"复制品"与访问真正的原始的局部变量,其语义效果是一样的呢? 

当变量是final时,若是基本数据类型,由于其值不变,因而:其复制品与原始的量是一样.语义效果相同.(若:不是final,就无法保证:复制品与原始变量保持一致了,因为:在方法中改的是原始变量,而局部内部类中改的是复制品) 

当 变量是final时,若是引用类型,由于其引用值不变(即:永远指向同一个对象),因而:其复制品与原始的引用变量一样,永远指向同一个对象(由于是 final,从而保证:只能指向这个对象,再不能指向其它对象),达到:局部内部类中访问的复制品与方法代码中访问的原始对象,永远都是同一个即:语义效 果是一样的.否则:当方法中改原始变量,而局部内部类中改复制品时,就无法保证:复制品与原始变量保持一致了(因此:它们原本就应该是同一个变量.) 

一句话:这个规定是一种无可奈何.也说明:程序设计语言的设计是受到实现技术的限制的.这就是一例. 因为:我就看到不少人都持这种观点:设计与想法是最重要的,实现的技术是无关紧要的,只要你作出设计与规定,都能实现.


现在我们来看,如果我要实现一个在一个方法中匿名调用ABSClass的例子: 

 public static void test(final String s){ 

     //或final String s = "axman"; 

  ABSClass c = new ABSClass(){ 

   public void m(){ 

      int x = s.hashCode();


      System.out.println(x);


   } 

  }; 

  //其它代码. 

 }


 从代码上看,在一个方法内部定义的内部类的方 法访问外部方法内局部变量或方法参数,是非常自然的事,但内部类编译的时候如何获取这个变量,因为内部类除了它的生命周期是在方法内部,其它的方面它就是 一个普通类。那么它外面的那个局部变量或方法参数怎么被内部类访问?编译器在实现时实际上是这样的:

  public static void test(final String s){ 

     //或final String s = "axman";

  class OuterClass$1 extends ABSClass{


   private final String s; 

   public OuterClass$1(String s){ 

      this.s = s;    

   } 

   public void m(){ 

      int x = s.hashCode();

      System.out.println(x);

   } 

  };

  ABSClass c = new OuterClass$1(s); 

  //其它代码. 

 }

即外部类的变量被作为构造方法的参数传给了内部类的私有成员. 

假如没有final,那么: 

 public static void test(String s){ 

     //或String s = "axman"; 

  ABSClass c = new ABSClass(){ 

   public void m(){ 

     s = "other"; 

   } 

  }; 

  System.out.println(s); 

 } 

 就会编译成: 

  public static void test(String s){ 

     //或String s = "axman";

  class OuterClass$1 extends ABSClass{


   private String s; 

   public OuterClass$1(String s){ 

      this.s = s;    

   } 

   public void m(){ 

     s = "other";


   } 

  }; 

   ABSClass c = new OuterClass$1 (s);

  }




 内部类的s重新指向"other"并不影响test的参数或外部定义的那个s.同理如果外部的s重新赋值内部类的s也不会跟着改变。 

 而你看到的 

  public static void test(String s){ 

     //或String s = "axman"; 

  ABSClass c = new ABSClass(){ 

   public void m(){ 

     s = "other"; 

   } 

  }; 

  System.out.println(s); 

 }


 在语法上是一个s,在内部类中被改变了,但结果打印的出来的你认为是同一的s却还是原来的"axman", 

 你能接收这样的结果吗? 

 所以final从语法上约束了实际上两个不同变量的一致性(表现为同一变量).

转载

http://feiyeguohai.iteye.com/blog/1500108

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,537评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,566评论 18 139
  • 这些天,有些忙,也没有画画。这两天上了下颜色,对颜色的把握,还是不太好,马克笔的笔触和配色的感觉都不太好,接下来要...
    小妖心心阅读 369评论 0 4
  • 拥有长达一生目标只有百分之三,百分之十的人较短目标,百分之二十七的人没有目标,抱怨社会!百分之六十的人目标模糊! ...
    纸上芭蕾阅读 263评论 0 0
  • 谨以此文章记录人生二十五年里第一次渴望的恋爱。提笔时,已柳暗,若无花明,当渐行渐远,渐行渐远。 人生若只如初见,年...
    Sy_Chester阅读 132评论 1 1