2

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

特别是我想尝试像这样对简单的 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..

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

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

4

2 回答 2

7

一种明显的方法是将“预定义”记录类移动到接口中:

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 {
    }
}
于 2020-12-09T12:38:19.470 回答
1

内部类以及密封类型似乎是您所追求的。Java 15 引入了密封类型作为预览功能。

您已经说过您想在一个文件中对 AST 进行建模。AST 是详尽无遗的。这种详尽性可以用内部类密封类型来建模。

在您的特定示例中,如果您在同一编译单元中定义超类型及其所有允许的子类型(子类型是内部类),编译器将自动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 { }
}

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

于 2020-12-09T14:28:38.787 回答