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

匿名类中的“变量示例可能尚未初始化”

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

匿名类中的“变量示例可能尚未初始化”

发生这种情况的原因是实现匿名类的方式。如果对代码稍作更改然后反编译,则可以看到以下内容:

    final Runnable other = null;    final Runnable example = new Runnable() {      @Override      public void run() {        System.out.println(other);      }    };

即,使匿名类引用不同的局部变量。现在可以编译了;我们可以使用进行反编译

javap
并查看匿名类的接口:

final class Example$1 implements java.lang.Runnable {  final java.lang.Runnable val$other;  Example$1(java.lang.Runnable);  public void run();}

Example$1
是Java内部引用匿名类的名称)。

这表明编译器已向带有

Runnable
参数的匿名类中添加了一个构造函数。它还有一个名为的字段
val$other
。该字段的名称应表明该字段与
other
局部变量有关。

您可以进一步研究字节码,并看到此参数已分配给

val$other

  Example$1(java.lang.Runnable);    Code:       0: aload_0       // This gets the parameter...       1: aload_1         // ...and this assigns it to the field val$other       2: putfield      #1       // Field val$other:Ljava/lang/Runnable;       5: aload_0       6: invokespecial #2       // Method java/lang/Object."<init>":()V       9: return

因此,这表明匿名类从其封闭范围访问变量的方式:在构造时将它们简单地传递给值。

这有望显示出为什么编译器会阻止您编写问题中的代码:它需要能够将对的引用传递

Runnable
给匿名类以进行构造。但是,Java评估以下代码的方式:

final Runnable example = new Runnable() { ... }

首先要充分评估右侧,然后将其分配给左侧的变量。但是,它需要右侧变量的值才能传递给生成的构造函数

Runnable$1

final Runnable example = new Example$1(example);

example
已不是先前声明是没有问题的,因为这个代码是语义相同:

final Runnable example;example = new Example$1(example);

因此,您得到的错误不是该变量无法解析-但是,

example
在将其用作构造函数的参数之前尚未分配值,因此出现编译器错误。


可能有人争辩说,这只是实现细节:不必将参数传递到构造函数中,因为

run()
在赋值之前无法调用该方法并不重要。

实际上,这不是真的:您可以

run()
在分配之前调用,如下所示:

final Runnable example = new Runnable() {  Runnable runAndReturn() {    run();    return this;  }  @Override public void run() {    System.out.println(example);  }}.runAndReturn();

如果

example
允许在匿名类内部进行引用,则可以编写此代码。因此,不允许引用该变量。



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

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

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