关于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

