Java 条记录和每个文件的单个 class 条限制

Java records and the single class per file limit

我正在试用 java 14 的新记录功能,目前处于预览状态。
我知道在 Java 中,每个文件必须恰好有一个 public class,但是新的记录语法非常好而且很短,拥有一堆文件似乎很浪费其中一行代码。

特别是我想尝试像这样对一个简单的 AST 建模,我认为将所有内容放在一个文件中确实提高了可读性和理解性。

package com.company;

public interface Expression {
}

public record IntExp(int value) implements Expression {
}

public record AddExp(Expression left, Expression right) implements Expression {
}

public record SubtractExp(Expression left, Expression right) implements Expression {
}

// Etc..

但不幸的是,这不会编译。
所以我的问题是:

有什么方法可以绕过这个限制,或者有什么方法可以将这样的代码全部保存在一个地方吗?

一个明显的方法是将 'pre-defined' 记录 类 移动到界面中:

package com.company;

public interface Expression {
    record IntExp(int value) implements Expression {
    }

    record AddExp(Expression left, Expression right) implements Expression {
    }

    record SubtractExp(Expression left, Expression right) implements Expression {
    }
}

内类,连同sealed types似乎就是你所追求的。 Java 15 引入了密封类型作为预览功能。

您已经声明要在一个文件中对 AST 建模。 AST 是 详尽的 。而这种 穷尽性 可以用内部 类 密封类型来建模。

在您的特定示例中,如果您在同一编译单元中定义超类型及其所有 permitted 子类型(子类型为内部 类),编译器会自动为你推断出 permits:

public sealed interface Expression {

    record IntExp(int value) implements Expression { }

    record AddExp(Expression left, Expression right) implements Expression { }

    record SubtractExp(Expression left, Expression right) implements Expression { }
}

在这里,编译器会自动将IntExpAddExpSubtractExp推断为permits并且不允许任何其他类型(在任何其他编译单元中声明) 既不扩展也不实现 Expression 接口。