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

关于IntelliJ允许下划线_作为标识符且编译检查延迟触发的技术咨询

IntelliJ允许下划线_作为标识符且编译检查延迟触发的原因解析

你遇到的这个情况其实挺有意思的,刚好踩中了Java编译器和IDE检查机制的一个小细节,我来给你拆解清楚:

首先得明确核心规则:从Java 9开始,单个下划线_就被正式规定为不能用作标识符(也就是变量名、方法名这类命名),OCP教材的说法完全没问题。那为什么IntelliJ在你只声明String _ = "Hello World";的时候不报错,反而等你尝试打印它才提示错误呢?

主要有这几个原因:

  • 编译器的“懒检查”逻辑
    Java自带的javac编译器本身就有这种特性:当你只是声明了一个用_命名的变量,但完全没使用它的时候,编译器可能不会立刻抛出编译错误——因为这个变量根本没参与程序逻辑,不会影响运行。但一旦你尝试调用它(比如用System.out.println(_)打印),它就成了程序的一部分,这时编译器就会严格检查它的合法性,直接报错。

  • IntelliJ的静态检查优先级
    IntelliJ的实时代码提示是跟着javac的规则走的,同时它会优先处理更影响程序运行的问题。对于未被使用的变量,它只会先标记成“未使用变量”的警告,不会立刻触发“无效标识符”的错误。只有当你开始使用这个变量时,它才会去验证这个命名的合法性,这时才会弹出Using '_' as a reference is not allowed的提示。

  • 延迟检查的设计初衷
    这其实是编译器设计里的一种权衡:如果一个标识符只是被声明但从来不用,它对程序运行没有任何实际影响,编译器犯不上立刻报错;但当它被实际调用时,就必须确保它符合规范,不然会影响程序执行,这时候才会严格检查。

给你举两个实际例子对比下:
只声明不使用的代码:

public class Test {
    public static void main(String[] args) {
        String _ = "Hello World";
    }
}

这时不管是javac还是IntelliJ,都不会报编译错误,最多提示你“变量未使用”;

但一旦你使用这个变量:

public class Test {
    public static void main(String[] args) {
        String _ = "Hello World";
        System.out.println(_);
    }
}

javac会直接抛出编译错误,IntelliJ也会实时弹出对应的错误提示。

其实这种行为不是IntelliJ独有的,用标准javac编译也会出现同样的情况,本质就是编译器对未使用标识符的检查优先级更低而已。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 07:45:27