首页 · ← SuperJ 手册 中文|EN

SuperJ 快速开始

SuperJ 是什么

SuperJ 是一门采用 Java 语法的系统编程语言,通过 LLVM 提前编译为原生代码。你写的是看起来像普通 Java 的代码 — 类、接口、泛型、枚举、异常 — 得到的是一个自包含的原生二进制,没有 JVM,没有 JIT 预热,也没有垃圾回收器。

不是 Java 的子集。它保留 Java 中让人愉悦、高效的部分,丢掉妨碍可预测原生性能的部分,并增加一层 Java 本不具备的系统级能力。结果就是读起来像 Java,跑起来像 C — 所以是 super Java。

为什么是"super",而不是"subset"

子集只会做减法。SuperJ 既做减法做加法:

保留 — Java 中好的部分 类与接口、单继承多接口、泛型(有界类型参数、通配符、菱形 <>)、枚举(每个常量可有主体)、带流作用域的 instanceof 模式匹配、方法引用(::)、可变参数、try/catch/finally@Override、完整的运算符与控制流集合,以及熟悉的 String/集合体验。

移除 — 妨碍原生性能或确定性的部分 线程、锁、synchronizedvolatilejava.util.concurrent(SuperJ 设计上就是单线程 — 用进程而非线程扩展);反射、ClassLoader 与 JPMS 模块(一切在编译期解决);lambda 与非静态内部类(没有隐藏的闭包机制 — 方法引用与静态嵌套类足以覆盖这些场景);自动装箱与受检异常;finalize()

新增 — 普通 Java 缺失的现代系统级能力

设计哲学

爱因斯坦有一句名言:任何聪明的傻瓜都能造出一个复杂的系统,但真正需要天才的是把系统做得尽可能简单 — 且不能再简单。SuperJ 的设计正是这一原则在一门语言上的具体实践。业界那些"显而易见的好东西" — 用线程做并发、用借用检查器做安全、源码级生态集成 — 每一个都是对真实问题的复杂解,而每一种情况下都存在一个更简单的解,它不是去管理问题,而是消除问题:

在每种情况下,复杂解是你假设问题必须被管理时会伸手去拿的;简单解是当你发现问题可以被消除时就能得到的。复杂性不仅更难用 — 它还是不可判定的 bug、非确定性,以及单语言锁定所在之处。更简单不仅仅是更好;它更可能是正确的。下面四条原则就是这一理念的具体实例。

  1. 单线程确定性。移除并发不是限制 — 它正是要点。每个进程一个事件循环线程意味着没有锁、没有数据竞争、没有调度抖动,以及你可以推理的代码。用进程(SO_REUSEPORT)横向扩展,而不是共享内存的线程。
  2. 没有 GC,没有停顿。arena 分配以确定性方式回收内存。实测的回报是近乎平坦的延迟曲线:HTTP 服务器在负载下保持 p99 ≈ p50 — 那种带 GC 的 JVM 费尽力气追求的尾部表现。
  3. 原生性能是基线。 AOT 编译到 LLVM、零分配热路径,以及系统 SDK 让 SuperJ 与已发表的最快框架处于同一档次 — 明文 HTTP 服务器的吞吐量在同等硬件上超过 TechEmpower 的 Rust/C 明文冠军,同时每个请求都执行完整的 HTTP 解析。
  4. 熟悉感降低了上述一切的成本。 Java 开发者立刻就能产出;新能力是可选的,不是前置条件。

安装

SuperJ 以预构建二进制发行版发布 — 从下载页下载你平台的 tarball,解压,并设置两个环境变量。唯一的宿主前置条件是一个 C 链接器(PATH 上的 clang/LLVM 22.x);其余一切都在包内。

下载并解压:

tar xzf superj-v1.3-<platform>-community.tar.gz   # macos-arm64 | linux-x86_64 | linux-arm64
export SJ_HOME="$PWD/superj"
export PATH="$SJ_HOME/bin:$PATH"

打开一个新 shell(或 source 你的 profile),然后:

superj --version        # 1.3 (community)

SDK 变体

SuperJ 有三种发行风味,区别在于SDK 如何交付目前只有 community 变体可供下载。你的代码在三者之间完全相同 — 只有链接路径不同。

三种变体:

变体你得到什么链接路径权衡
community预构建静态归档(libsuperj_sdk.a编译器链接归档;clang 链接最终二进制链接最快;无跨模块全程序优化。安装体积最小。可供下载。
enterprise预构建 SDK IR(sdk.ll)+ 运行时对象编译器 llvm-link 将 sdk.ll 与你的 IR 链接;clang -O3 整个程序跨 SDK + 用户代码的全程序优化(全局内联、死代码消除);链接较慢,运行时性能更好。
vipSDK 源码(.sj 文件,无预构建产物)编译器将 SDK 与你的源码一起编译(--sdk-source);clang 链接最大优化 + 完整源码供审计/修改;构建最慢。

你的代码在三者之间完全相同 — superj compile 会从 $SJ_HOME/sdk 自动检测已安装的模式,所以你通常不需要操心:

superj compile app.sj                 # 自动检测已安装模式,输出 IR
superj compile app.sj --link          # … 并链接一个可执行文件(始终 -O3)
superj compile app.sj --link --enterprise   # 强制全程序 LTO(需要 sdk.ll)

superj compile --link 始终向 clang 传入 -O3(除非指定 --debug)。显式的 --sdk-path <dir>(community)、--sdk-source <dir>(VIP)和 --enterprise 会覆盖自动检测。一个不导入 sj.* 中任何内容的程序是完全独立的 — 根本不会链接 SDK。

优化标志

标志效果
(默认)-O3 — 始终如此,除非指定 --debug
--enterprise全程序 LTO:llvm-link sdk.ll + clang -O3 合并后的模块(跨编译单元内联/去虚化)
--no-bounds-check禁用数组越界检查(热数值循环;约 1.1-1.5 倍加速)
--simd <level>sse2(默认,x86)、avx2(x86 256 位)、none(禁用)。ARM NEON 始终开启(此标志为空操作)。
--target-cpu <cpu>clang -mcpu=<cpu>(例如 nativeapple-m2
--debug-O0 -g(1:1 调试行映射;无优化)

最大性能:

superj compile app.sj --sdk-source "$SJ_HOME/sdk/sj" --enterprise --link \
    --no-bounds-check --simd avx2 --target-cpu native --output app
# 或通过构建系统:
superj build --release --enterprise

我用的是哪个变体?

检查 $SJ_HOME/sdk/build/ 里的内容:

ls $SJ_HOME/sdk/build/

切换变体意味着重新运行另一个安装器。

Hello, SuperJ

SuperJ 在 superj 二进制中内置了一个受 Cargo 启发的构建系统。一条命令搭建项目;再两条命令构建并运行:

superj new myapp        # 脚手架:Build.sj + src/myapp/Main.sj + .gitignore
cd myapp
superj run               # 编译 + 链接 + 运行,一步到位

你应该看到:

Hello from myapp

脚手架生成的项目:

myapp/
  Build.sj            ← 清单(名称、版本、入口、依赖)
  .gitignore          ← 忽略 target/
  src/myapp/Main.sj   ← package myapp; class Main { public static void main(String[] args) { ... } }

编辑 src/myapp/Main.sj

package myapp;

public class Main {
    public static void main(String[] args) {
        System.out.println("hello from superj");
    }
}

然后:

superj run               # 重新构建 + 运行
superj build --release   # 优化构建 -> target/release/myapp
superj check             # 全项目类型检查(无代码生成/链接)

完整的构建系统功能 — Build.sj 清单字段、路径与 git 依赖、工作区、profile、构建钩子、feature flag、superj addsuperj cleansuperj test — 参见 构建系统

使用 SDK

SuperJ SDK 随包发布在 $SJ_HOME/sdk/。一个导入了 sj.* 类(集合、HTTP、JSON、SEDA、加密、…)的程序会自动针对已安装的 SDK 编译 — 无需任何标志:

superj run               # 自动检测已安装的 SDK 模式

要查看完整的 SDK API 全貌 — 每个类、方法与签名集中在一个文件 — 阅读 $SJ_HOME/sdk/build/SDK_API.md(由 superj sdk-api 生成)。查看单个类:

superj doc sj.http.Router            # 打印 Router 的方法 + 签名
superj doc sj.util.IntArrayList      # 打印 IntArrayList 的接口面
superj doc --list                    # 打印每个 SDK 类(FQN + 标签)

一组精选的约 30 个示例,覆盖语言表面与所有 SDK 能力,位于 examples/INDEX.md — 按能力(http、json、seda、collections、…)搜索它,读一个示例,你就掌握了模式。

从源码构建 / 贡献者

上面的 curl | sh 路径面向最终用户。如果你要为 SuperJ 本身做贡献,贡献者指南(AGENTS.md)与开发环境设置位于源码仓库中。

IntelliJ 插件(可选)

SuperJ 在 plugins/intellij/ 下附带一个 IntelliJ IDEA 插件(语法高亮、跳转到声明、运行配置)。该插件是可选的使用编译器并不需要它 — 它只是一个 IDE 便利工具。

发行版 tarball 的 plugins/intellij/ 目录在能够构建时包含插件 jar。构建插件需要构建机器上有 JDK 17 和 IntelliJ IDEA 安装(它在编译时链接 IDE 的 jar)。pack.sh 发布步骤会按需尝试构建它:

所以一个没有 IDE 的无头/CI 构建机器产出的是完全可用的 SuperJ 安装,只是没有 IDE 插件。安装后自行构建:

cd plugins/intellij
JAVA_HOME=<jdk-17> mvn -DskipTests -Dij.home <IntelliJ.app/Contents> package

把生成的 target/superj-intellij-*.jar 放到你的 $SJ_HOME/plugins/intellij/。IDE 安装步骤见源码仓库中的贡献者指南。

接下来去哪

SuperJ — manual · generated from getting-started.md at pack time · Powered by superJ — this site is served by superj_web 中文|EN