Java 有“a”这样的东西吗;“本地接口”;在爪哇?

Java 有“a”这样的东西吗;“本地接口”;在爪哇?,java,interface,local-class,Java,Interface,Local Class,Java允许我定义本地抽象类,如本例所示: 公共类Foo{ 公共图书馆{ 抽象类Bar{//Bar是foo()中的一个本地类。。。 抽象空条(); } 新建条(){//…并可以匿名实例化 空条(){ System.out.println(“Bar!”); } }.bar(); } } 出于某种原因,当我尝试定义“本地接口”而不是本地类时,如下所示: 公共类Foo{ 公共图书馆{ 接口栏{//Bar应该是本地接口。。。 空心钢筋(); } 要匿名实例化的新Bar(){/ 空条(){ System

Java允许我定义本地抽象类,如本例所示:

公共类Foo{
公共图书馆{
抽象类Bar{//Bar是foo()中的一个本地类。。。
抽象空条();
}
新建条(){//…并可以匿名实例化
空条(){
System.out.println(“Bar!”);
}
}.bar();
}
}
出于某种原因,当我尝试定义“本地接口”而不是本地类时,如下所示:

公共类Foo{
公共图书馆{
接口栏{//Bar应该是本地接口。。。
空心钢筋();
}
要匿名实例化的新Bar(){/
空条(){
System.out.println(“Bar!”);
}
}.bar();
}
}

Java抱怨“成员接口栏只能在顶级类或接口中定义”。这有什么原因吗?还是我遗漏了我犯的一个错误?

Java语言规范没有告诉您为什么它是这样设计的,但它确实描述了什么是允许的,什么是不允许的

A具有以下形式

MethodBody:
    Block 
    ;

因此,允许使用类声明,但不允许使用接口



我们可以说,从调用方的角度来看,拥有本地接口不是很有用。它没有任何作用。接口是用来描述行为的,但是由于接口是本地的,所以没有调用方可以使用它。您也可以在类中定义和实现行为。

在JLS中根本没有定义。它根本不存在

由于一个薄弱的原因,根据:

所有本地类均为内部类(§8.1.3)

接口不能是内部的():

成员接口(§8.5)是隐式静态的,因此它们从不被视为内部类

所以我们不能有一个本地接口

我猜,这是@SotiriosDelimanolis发现InterfaceDeclaration不是块语句之外的内容。

本地接口(和枚举)是随着记录类功能引入的:

  • 在JDK15中作为预览功能(JEP384)-请参阅
  • 在JDK 16中作为永久特性(JEP 395)-请参阅
不幸的是,这个特性在文档中有点模糊,但它可以工作

两个版本都允许编写如下代码:

public class Main {

    public int foo() {

        interface Experimentable {
            int bar();
        }

        Experimentable e = new Experimentable() {
            @Override
            public int bar() {
                return 0;
            }
        };

        return e.bar();
    }

    public static void main(String[] args) {
        System.out.println(new Main().foo());
    }

}

为什么本地抽象类不能完成这项工作?@TedHopp确实如此。在我看来,界面应该是“更干净的”。在我的实际代码中使用本地类的唯一原因是让它实现另外两个接口(请参阅)。哇,我甚至不知道在方法中定义本地类是可能的。我只是好奇,有没有人知道一些真实世界的例子,其中这个构造实际上是有用的?@JakubJirutka我用它们来说明这个问题:我认为你太努力了,试图限制接口的范围。让它成为班级的私人成员。这是一个不错的设计。有趣的是:如果你看一下“内部类”(internalclasses)的“官方”示例,它显示的内部类定义(eventirator)就在相应的接口定义(datastructurediterator)的旁边,我猜对称性也应该称之为“内部”…:)@马库萨。嵌套接口是隐式静态的。你不能有一个内部接口。啊!现在有道理了!接口是隐式静态的!这就是原因!如果我试图将本地类定义为静态类,它也会抱怨(
…static abstract class Bar…
在我的第一个示例中会引发错误)。当然,在一个方法中把任何东西定义为“静态”是没有意义的…@MarkusA。小心你试图建立的联系。一个本地类不是它所定义的类的成员,那么为什么会有一个接口?@SotiriosDelimanolis Point。。。我通常认为接口在编程上(虽然不是逻辑上)主要等同于抽象类(没有字段,只有抽象方法)。因此,对于这种情况,界面上的隐式“静态”有效地再次恢复了对应关系。。。附言:我喜欢这个例子14.3-1。(本地类声明)在链接中。真是一团糟!:)但仔细看两遍,几乎所有的范围都与局部变量声明的工作方式完全一致。。。Java内部的深层含义是有意义的(至少对我来说)…我想接口的目的是“定义外部调用方的行为”,这在这种情况下是没有意义的,这可能是他们决定不允许它的原因。我认为Radiodef找到了真正的原因(见下文)。@MarkusA。至于真正的原因,我认为那只是“它不存在”。接口本地不在规范中。@Radiodef这是它抛出异常的真正原因,但不是规范中没有的真正原因。;)总的来说,我认为我从来没有在Java中遇到过这样一个例子:我最终没有找到一个理由来解释为什么某些东西应该被禁止(这并不是因为没有深入挖掘)。在大多数情况下,我发现JLS具有令人印象深刻的意义。我总是很惊讶他们设法考虑了多少完全模糊的结构。我现在能记得的唯一一件对我来说仍然没有意义的事情是三元运算符的自动装箱行为。:)
public class Main {

    public int foo() {

        interface Experimentable {
            int bar();
        }

        Experimentable e = new Experimentable() {
            @Override
            public int bar() {
                return 0;
            }
        };

        return e.bar();
    }

    public static void main(String[] args) {
        System.out.println(new Main().foo());
    }

}