特别说明:因为Java和Kotlin JVM机制类似,所以在本文章中采用Kotlin语言,有兴趣的同学也可以自己使用Java语言重现。
前提:在Windows系统下搭建的开发环境(至于为什么指明在Windows系统下,到后面就会知道了)
新建一个Kotlin文件,在内部定义简单的两个数据类,和一个主函数入口
data class Abc(val name: String)
data class ABC(val name: String)
fun main(args: Array<String>) {
println(Abc("Abc"))
println(ABC("ABC"))
}
编译成功,但是运行并不理想,没错,报异常了(如下图):
找不到类?开什么国际玩笑,明明就有那个类啊,别急,让我们看看编译出来的class文件,看看到底出了什么问题(如下图)。
看到生成的class文件,只有Abc.class
文件,但是里面的内容,却是ABC
类的代码,这不合理啊。下面就来分析一下原因。
前面提到,这个测试是基于Windows系统下,而在Windows系统下,文件名是不区分大小写的,也就是Abc.class
和ABC.class
会被认为是同一个文件,编译器会将一个文件内的多个类文件变异成多个class文件,以上代码在编译过程中,先编译Abc
类生成Abc.class
文件,并将编译的代码写入改文件,当编译ABC
类时,按理应该生成ABC.class
文件的,但是因为已经存在Abc.class
文件,被认为文件已经存在,就直接更新了文件内部的内容而已,所以导致Abc
这个类就找不到了,于是出现了以上的问题。
另外,在Linux等其他系统,文件名区分大小写的情况下,就不会出现上面的错误(这个大家可以各自去验证),所以,大家在开发过程中,要做到命名规范很重要:
- 对于类声明,尽量使用单独的类文件编写(以上例子,在Windows系统下无法在同一包名下同时创建
Abc.java
和ABC.java
) - 切忌在同一个文件内声明多个名称只有大小写区分内部类。