Java源文件必须以.java为后缀,编译生成的字节码文件固定为.class;javac和java工具链硬编码识别这两种后缀,不可更改,否则报错或加载失败。

Java源文件必须用.java后缀
Java编译器javac只识别.java结尾的文件,其他后缀(如.txt、.jav)即使内容完全正确,也会报错:error: class, interface, or enum expected。这不是语法问题,而是编译器根本没把文件当Java源码读。
常见误操作:
- 从网页复制代码粘贴到记事本,保存时未手动输入
.java,系统默认加了.txt(如HelloWorld.java.txt) - IDE导出时选错格式,或手动重命名漏掉
.java - Linux/macOS下文件名大小写敏感,
helloworld.java和HelloWorld.java被视为不同文件,但类名必须匹配,否则运行时报NoClassDefFoundError
编译生成的字节码文件固定为.class
javac不会接受任何自定义字节码后缀,输出永远是.class。哪怕用-d指定输出目录,文件扩展名也不可更改。
关键点:
立即学习“Java免费学习笔记(深入)”;
- 一个
.java文件可能生成多个.class:内部类、匿名类、Lambda表达式都会各自产出独立的.class文件(如Outer$Inner.class) -
.class文件名严格对应类名,不是源文件名:如果A.java里定义了public class B,编译会失败;反之,若B.java里定义了public class B,编译后就是B.class - JVM只认
.class,不关心它是否来自Java——Kotlin、Scala编译后也是.class,只要符合JVM规范就能加载
为什么不能改这些后缀?
javac源码里直接写死匹配"*.java",java命令启动JVM时,类加载器(如URLClassLoader)按ClassName.class路径查找资源,中间没有配置项或钩子允许替换后缀。
试图绕过:
- 用
zip或jar打包时改后缀?不行——java -jar要求MANIFEST.MF声明Main-Class,且JAR内仍需是.class - 用字节码操作库(如ASM)生成非
.class文件?可以生成,但JVM拒绝加载,报UnsupportedClassVersionError或ClassFormatError
实际开发中容易忽略的细节
多模块项目里,IDE(如IntelliJ)可能把target/classes或build/classes设为输出目录,但如果你手动清理再用javac编译,得确认-d指向的是同一位置,否则java命令找不到.class——它不会自动扫描子目录,除非用-cp显式指定。
还有个坑:java HelloWorld命令里的HelloWorld是类名,不是文件名,所以不能带.class后缀;而javac HelloWorld.java里的HelloWorld.java是文件名,必须带.java。这两个后缀谁都不能省,也不能互换。










