You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 14预览版Records特性:如何突破单文件公共类限制?

解决Java单文件中放置多个Public Records的问题

你提的这个需求太贴合实际了——用Records来建模AST的时候,每个节点类型都短小精悍,单独建一个文件确实有点冗余,完全没必要。不过Java的单文件只能包含一个顶级public类/record的规则确实会卡住这个场景,下面给你几个实用的解决方案:

方案1:改为包私有(去掉public修饰符)

如果你的AST相关代码都在同一个包下使用,最简单的办法就是把所有Record的public修饰符去掉,让它们变成包私有。这样既可以把所有代码放在一个文件里,同一包内的其他类也能正常访问这些Record。

修改后的代码示例:

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 { }
// 其他AST节点...

这种方式最简洁,完全不需要额外结构,适合内部包内使用的场景。

方案2:嵌套在公共类/接口中

如果需要这些Record对外暴露(比如跨包使用),可以把它们嵌套在一个公共的顶级类或者接口里面,作为内部public record。这样外部代码可以通过Expression.IntExp这样的路径访问,同时所有代码都集中在一个文件里。

示例代码:

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 { }
    // 其他AST节点...
}

这种方式既保持了公共访问性,又满足了代码集中的需求,非常适合对外提供AST模型的场景。

方案3:结合密封类(Java 16+)

如果你的项目已经升级到Java 16或更高版本,推荐用**密封类(Sealed Classes)**来配合Records建模AST。密封类可以明确限制哪些类可以实现它,完美契合AST节点的封闭性,同时你可以把所有实现类(Records)放在同一个文件里,无论是作为包私有还是嵌套成员都可以。

示例代码:

package com.company;

public sealed interface Expression permits IntExp, AddExp, SubtractExp { }

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 { }
// 其他AST节点...

(注:这里如果把Records改成包私有,也可以放在同一个文件里,密封类的permits列表依然能识别它们)

为什么原代码无法编译?

Java的核心规则是:每个顶级public类/record必须放在与其同名的.java文件中。你原来的代码里有多个顶级public record,它们各自需要对应的IntExp.java、AddExp.java等文件,所以编译器会报错。上面的方案都是通过规避“顶级public”这个限制来实现代码集中的。

内容的提问来源于stack exchange,提问作者james lessy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:40:01