本地类定义:为什么这样做

时间:2011-09-27 08:29:05

标签: java android

为什么以下样式的代码有效:

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

6 个答案:

答案 0 :(得分:8)

这是一个匿名类声明。有关详细信息,请参阅JLS的section 15.9.5

  

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

实际receiver变量的类型只是BroadcastReceiver - 但创建的对象的类型是ContainingClass$1的实例,其扩展{{1 }}

答案 1 :(得分:4)

它有效,因为您使用的是anonymous class

答案 2 :(得分:1)

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

答案 3 :(得分:1)

这称为匿名内部类。如此名称所示,此类没有名称。

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

答案 4 :(得分:1)

在第一个示例中,类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

答案 5 :(得分:0)

  

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

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

  

现在是receiver == reciver2

显然不是:它们是两个不同的实例(即使它们扩展 BroadcastReceiver)。