【问题标题】:Local class definitions: why does this work本地类定义:为什么会这样
【发布时间】:2011-09-27 08:29:04
【问题描述】:

为什么以下代码风格有效:

BroadcastReceiver receiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        //do something based on the intent's action
    }
}

我希望它是:

private class MyBroadcastReceiver extends BroadcastReceiver () {
    public void onReceive(Context context, Intent intent) {
        //do something based on the intent's action
    }
}

MyBroadcastReceiver receiver = new MyBroadcastReceiver();

在上面的第一段代码中,编译器如何知道receiver 的类型是MyBroadcastReceiver 而不是BroadcastReceiver?这不是模棱两可吗?为什么允许这样做?

如果我定义:

BroadcastReceiver receiver2 = new BroadcastReceiver();

现在是receiver == reciver2

编辑:
广播接收器 http://developer.android.com/reference/android/content/BroadcastReceiver.html

【问题讨论】:

标签: java android


【解决方案1】:

这是一个匿名类声明。详情请参阅 JLS 的section 15.9.5

匿名类声明由编译器自动从类实例创建表达式派生。

receiver 变量的类型实际上只是BroadcastReceiver - 但创建的对象类型是ContainingClass$1 的一个实例,它扩展了BroadcastReceiver

【讨论】:

    【解决方案2】:

    之所以有效,是因为您使用的是anonymous class

    【讨论】:

      【解决方案3】:

      您在这里创建了一个未命名的类,它扩展了 BroadcastReciever。这在 Java 中很常见,例如创建监听器。由于未命名的类扩展了 BroadcastReciever,它可以被该类型的引用使用。

      【讨论】:

        【解决方案4】:

        这称为匿名内部类。正如这个名字所表明的,这样的一个类没有名字。

        它将被编译成一个.class文件名EnclosingClass$1.class。 receiver2 变量的类文件将是EnclosingClass$2.class

        【讨论】:

          【解决方案5】:

          在第一个示例中,receiver 类不是 MyBroadcastReceiver 的实例;它是 BroadcastReceiver 的匿名实例。

          BroadcastReceiver receiver = new BroadcastReceiver() {
              public void onReceive(Context context, Intent intent) {
          
              }
          }
          
          MyBroadcastReceiver myReceiver = new MyBroadcastReceiver();
          
          (receiver instanceof MyBroadcastReceiver); // is FALSE
          (receiver instanceof BroadcastReceiver); // is TRUE
          

          【讨论】:

            【解决方案6】:

            在上面的第一段代码中,编译器如何知道接收器的类型是MyBroadcastReceiver 而不是BroadcastReceiver

            它没有,您只是创建了一个 anonymous class 的实例,该实例扩展了具有特定实现的 BroadcastReceiver

            现在是receiver == reciver2

            显然不是:它们是两个不同的实例(尽管它们都扩展 BroadcastReceiver)。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-02-09
              • 2019-10-10
              • 1970-01-01
              • 2018-10-15
              • 1970-01-01
              • 2021-11-03
              • 1970-01-01
              相关资源
              最近更新 更多