搜索
当前位置: sk彩票 > 对象型方法 >

java 中为什么引用外部类的变量和方法都要是final内型 的

gecimao 发表于 2019-06-27 15:30 | 查看: | 回复:

  可选中1个或多个下面的关键词,搜索相关资料。也可直接点“搜索资料”搜索整个问题。

  Thinking In Java里面的说法(唯一正确的说法): 如果定义一个匿名内部类,并且希望它使用一个在其外部定的对象,那么编译器会要求其参数引用是final 的。以下是分析过程:

  再来看Java虚拟机是怎么实现这个诡异的访问的:有人认为这种访问之所以能完成,是因为arg是final的,由于变量的生命周期,事实是这样的吗?方法栈都不存在了,变量即使存在,怎么可能还被访问到?试想下:一个方法能访问另一个方法的定义的final局部变量吗(不通过返回值)?

  研究一下这个诡异的访问执行的原理,用反射探测一下局部内部类 。编译器会探测局部内部类中是否有直接使用外部定义变量的情况,如果有访问就会定义一个同类型的变量,然后在构造方法中用外部变量给自己定义的变量赋值,而后局部内部类所使用的变量都是自己定义的变量,所以就可以访问了。见下:

  A$1$B类型的对象会使用自定义的var$arg变量,而不是shout()方法中的final int arg变量,当然就可以访问了。

  那么为什么外部变量要是final的呢?即使外部变量不是final,编译器也可以如此处理:自己定义一个同类型的变量,然后在构造方法中赋值就行了。原因就是为了让我们能够挺合逻辑的直接使用外部变量,而且看起来是在始终使用外部的arg变量(而不是赋值以后的自己的字段)。

  考虑出现这种情况:在局部内部类中使用外部变量arg,如果编译器允许arg不是final的,那么就可以对这个变量作变值操作(例如arg++),根据前面的分析,变值操作改变的是var$arg,而外部的变量arg并没有变,仍然是5(var$arg才是6)。因此为了避免这样如此不合逻辑的事情发生:你用了外部变量,又改变了变量的值,但那个变量却没有变化,自然的arg就被强行规定必须是final所修饰的,以确保让两个值永远一样,或所指向的对象永远一样(后者可能更重要)。

  还有一点需要注意的是内部类与方法不是同时执行的,比如实现ActionListener,只有当事件发生的时候才会执行,而这时方法已经结束了。

  根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变:设计或效率。

  final类不能被继承,没有子类,final类中的方法默认是final的。

  注意:父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。

  final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。

  如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。

  第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。

  final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。

  另外,final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。

  //出错,final变量的值一旦给定就无法改变 //t.D=71; //出错,final变量的值一旦给定就无法改变

  当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。

  Test4().f1(2); } public void f1(final int i){ //i++; //i是final类型的,值不允许改变的. System.out.print(i); } }我是在一个内部类中引用外部那个类的变量,如果引用的不是final型变量就会报错

  final类不能被继承,没有子类,final类中的方法默认是final的。

  问题重点:final的变量是不可修改的,比如你用final声明数据库账号、密码,你不可能改变它,所有定义成final之后才被引用,增加了安全性,要想修改只能去final声明那里修改,在程序调用中是不可能修改的!

  展开全部其实不一定非得那样,不考虑其他的你可以在一个类中定义成static 然后,在另一个类中通过:

  类名.属性 或 类名.方法调用。不过这样做的话属性值就可能被调用的类改变,而且很耗内存,一个合格的程序员在选择方法时通常会考虑内存、性能、效率等。

  第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。更多追问追答追问我是在一个内部类中引用外部那个类的变量,如果引用的不是final型变量就会报错追答其实fanal定义的变量就是一个常量!写成final在内部类中用一定不会错!

  就是我写了个内部类,引用了外部内的变量,然后提示说只能引用final类型的变量,程序是没问题了,我想知道这是为什么!系统都说必须引用final类型的外部变量我知道肯定有其道理。

  lz 表达不清楚,居然说是引用外部类的变量,是不是说的内部类? 也就是内部类使用外部类的变量,必须是final???

  楼上的都是在装内行 答非所问 回答的都是final的意义; 这个问题当时我也只是强记的,希望楼主知道后也能告知声哦

本文链接:http://moodyjews.net/duixiangxingfangfa/715.html
随机为您推荐歌词
推荐文章

联系我们 | 关于我们 | 网友投稿 | 版权声明 | 广告服务 | 站点统计 | 网站地图

版权声明:本站资源均来自互联网,如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

Copyright @ 2012-2013 织梦猫 版权所有  Powered by Dedecms 5.7
渝ICP备10013703号  

回顶部