java记录和每个文件的单个类限制

vx6bjr1n  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(332)

我正在试用Java14的新记录功能,目前正在预览中。
我知道在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..

但不幸的是,这将无法编译。
所以我的问题是:
有没有办法绕过这个限制,或者有什么办法把这样的代码放在一个地方?

ix0qys7i

ix0qys7i1#

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

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 {
    }
}
33qvvth1

33qvvth12#

内部类以及密封类型似乎是您所追求的。Java15引入了密封类型作为预览特性。
你说过你想在一个文件中建模一个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 { }
}

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

相关问题