【问题标题】:Why can I instantiate an interface without declaring a class? [duplicate]为什么我可以在不声明类的情况下实例化接口? [复制]
【发布时间】:2016-05-23 19:09:04
【问题描述】:

所以在 Java 中,可以在不创建显式类的情况下实例化接口

public interface Foo {
  public void OnNotify()
}

假设我在其他地方执行以下操作,例如在订阅方法中

public void Subscribe()
{
  final int someInt = 5;

  Foo bar = new Foo() {
    final int value = someInt;

    @Override
    public void OnNotify()
    {
        Log.d("Debug", "You are being notified that I hold the value " + value);
    }
  }

  someObject.AddSubscription(bar);
}

这在 Android 中广泛用于设置事件的侦听器。

为什么会这样,这种实例化有一个特殊的名称吗?这可能在某种程度上与 lambda 函数有关吗?

如果我想把它交给这个实例化的接口来保存,为什么我需要创建一个“最终”变量。例如,我想传递 for 循环的当前迭代“i”来识别订阅引用的数组索引。我需要声明一个final变量来保存'i',然后将它传递给实例化的接口。

编辑: 我还在问为什么我可以在不先创建类的情况下实例化一个接口,以及它叫什么。不知道这是什么,我不可能找到重复的问题,它没有涵盖 Java 匿名类是什么。

【问题讨论】:

  • 你不是在实例化一个接口,你是在实例化一个匿名类。
  • 正如其他人已经指出的那样。这是一个匿名类,它只是创建使用您的接口的类的一种简单方法
  • @azurefrog 如果您可以以答案的形式发布,我可以将其标记为该问题的答案。

标签: java android interface


【解决方案1】:

为什么会这样,这种实例化有一个特殊的名称吗?这可能在某种程度上与 lambda 函数有关吗?

  1. 我不知道这个有什么“特殊名称”。我一般把它称为“接口实现声明”。这只是我,也许这不准确或不正确。
  2. 我相信它们不是,因为除了语法差异之外,我将 lambdas 视为类似方法类的结构,并且这种形式是覆盖对象类型的方法。传递接口对象时,您传递的是类型的引用。

如果我想把它交给这个实例化的接口来保存,为什么我需要创建一个“最终”变量。

我查看并理解它的方式是因为这个声明内联而不是在单独的类中并没有完全改变接口仍然是什么。 In the Java programming language, an interface is a reference type, similar to a class, that can contain only constants, method signatures, default methods, static methods, and nested typesLink

接口需要有一个常量,对我来说final 是一个与 C/C++ 关键字const 类似的关键字,因为它不是保存值,而是对您的类型的引用'已经宣布。这些值是不可变的,防止任何复制和更改,因为它们只包含对值位置的引用。

因此,总的来说,我认为像您所说明的那样的接口声明并不是在声明实际接口类的实例,而是在创建该类型的对象,并且该对象是内存中的一个新位置对这些方法和成员的引用(如类)。

希望这会有所帮助。我通常不喜欢自愿回答我不是 100% 确定的事情,并希望这是一个评论(但仍然缺乏代表),但希望它有助于澄清一些事情。

您也可以阅读 Java 语言规范 here 以获取有关接口的更多信息。希望有帮助。

【讨论】:

    猜你喜欢
    • 2014-06-20
    • 1970-01-01
    • 2016-04-05
    • 2022-07-22
    • 2014-11-14
    • 2015-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多