栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如果非最终字段的值可以更改,那么如何在非匿名字段类中使用非最终字段?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如果非最终字段的值可以更改,那么如何在非匿名字段类中使用非最终字段?

方法调用的局部变量(

final
内部类必须可以访问)和实例的私有数据成员之间有很大的区别。

内部类可以访问包含的实例,也可以访问该实例的所有成员

final
。不需要将它们定型,因为(在您的情况下)已通过引用它们
Foo.this
。因此,在访问您的
i
成员时,内部类实际上是在访问
Foo.this.i
,只是如果引用没有它,就可以隐含
Foo.this
(如
this
)。

但是匿名类的代码无法以这种方式访问​​局部变量,因为它们(当然)不是包含类的实例成员。因此,相反,编译器做了一件非常有趣的事情:为每个局部变量创建 匿名
类的实例成员

final
,并在创建匿名类的实例时,使用局部变量的值初始化这些成员。

让我们看一下它:

public class InnerEx {    public static final void main(String[] args) {        new InnerEx().test("hi");    }    private void test(String arg) {        final String localVar = arg;        Runnable r = new Runnable() { public void run() {     System.out.println(localVar); }        };        r.run();    }}

编译后,我们得到

InnerEx.class
InnerEx$1.class
。如果我们反编译
InnerEx$1.class
,我们将看到:

class InnerEx$1 implements java.lang.Runnable {  final java.lang.String val$localVar;  final InnerEx this$0;  InnerEx$1(InnerEx, java.lang.String);    Code:       0: aload_0   1: aload_1   2: putfield      #1       // Field this$0:LInnerEx;       5: aload_0   6: aload_2   7: putfield      #2       // Field val$localVar:Ljava/lang/String;      10: aload_0  11: invokespecial #3       // Method java/lang/Object."<init>":()V      14: return  public void run();    Code:       0: getstatic     #4       // Field java/lang/System.out:Ljava/io/PrintStream;       3: aload_0   4: getfield      #2       // Field val$localVar:Ljava/lang/String;       7: invokevirtual #5       // Method java/io/PrintStream.println:(Ljava/lang/String;)V      10: return        }

请注意,实例成员名为

val$localVar
,这是为代表调用中的局部变量而创建的实例成员
InnerEx#test



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/386851.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号