Error[8]: Undefined offset: 16, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

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

方法调用的局部变量

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.class
。如果我们反编译
InnerEx.class
,我们将看到:

class InnerEx implements java.lang.Runnable {  final java.lang.String val$localVar;  final InnerEx this
val$localVar
; InnerEx(InnerEx, java.lang.String); Code: 0: aload_0 1: aload_1 2: putfield #1 // Field this
InnerEx#test
: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 }

请注意,实例成员名为[+++],这是为代表调用中的局部变量而创建的实例成员[+++]。



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 17, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

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

方法调用的局部变量

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.class
。如果我们反编译
InnerEx.class
,我们将看到:

class InnerEx implements java.lang.Runnable {  final java.lang.String val$localVar;  final InnerEx this
val$localVar
; InnerEx(InnerEx, java.lang.String); Code: 0: aload_0 1: aload_1 2: putfield #1 // Field this
InnerEx#test
: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 }

请注意,实例成员名为,这是为代表调用中的局部变量而创建的实例成员[+++]。



)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
如果非最终字段的值可以更改,那么如何在非匿名字段类中使用非最终字段?_随笔_内存溢出

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

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

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

方法调用的局部变量

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.class
。如果我们反编译
InnerEx.class
,我们将看到:

class InnerEx implements java.lang.Runnable {  final java.lang.String val$localVar;  final InnerEx this
val$localVar
; InnerEx(InnerEx, java.lang.String); Code: 0: aload_0 1: aload_1 2: putfield #1 // Field this
InnerEx#test
: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 }

请注意,实例成员名为,这是为代表调用中的局部变量而创建的实例成员。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4957810.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-13
下一篇 2022-11-13

发表评论

登录后才能评论

评论列表(0条)

保存