第二个空值的解释为java.lang.Class#getClassLoader()
返回该类的类加载器。一些实现可能会使用
null 代表引导类加载器。这个方法会返回
如果此类是由引导程序加载的,则在此类实现中为 null
类加载器。
所以,这就是为什么classOf[Object].getClassLoader
返回 null,它由引导类加载器加载(它位于 rt.jar 中,更具体地说,它位于 $JAVA_HOME/lib 中的 jar 中)。
第一个空值更难解释。看来 Scala 按原样保留系统类加载器,只将选项 -cp 添加到它自己的类加载器(scala/util/ClassLoader.scala 中的 ScalaClassLoader)。
使用以下内容:
object Test {
def main(args:Array[String]) = {
println(ClassLoader.getSystemClassLoader)
println(this.getClass.getClassLoader)
println(classOf[Object].getClassLoader)
}
}
并运行它:
$ scala -cp /temp Test
我们得到以下输出:
sun.misc.Launcher$AppClassLoader@11b86e7
URLClassLoader(
file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/resources.jar
file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/rt.jar
file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/jsse.jar
file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/jce.jar
file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/charsets.jar
file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/ext/dnsns.jar
file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/ext/localedata.jar
file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/ext/sunjce_provider.jar
file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/ext/sunmscapi.jar
file:/C:/developpement/utils/jdk1.6.0_22/jre/lib/ext/sunpkcs11.jar
file:/C:/DEVELO~1/scala/SCALA-~1.1/bin/../lib/jline.jar
file:/C:/DEVELO~1/scala/SCALA-~1.1/bin/../lib/scala-compiler.jar
file:/C:/DEVELO~1/scala/SCALA-~1.1/bin/../lib/scala-dbc.jar
file:/C:/DEVELO~1/scala/SCALA-~1.1/bin/../lib/scala-library.jar
file:/C:/DEVELO~1/scala/SCALA-~1.1/bin/../lib/scala-swing.jar
file:/C:/DEVELO~1/scala/SCALA-~1.1/bin/../lib/scalap.jar
file:/C:/temp/
)
null
因此,系统类加载器保持不变,但 Scala 类加载器从 -cp 中获取添加到其中的项目。
这个故事的寓意是:如果您想从类路径访问资源,请不要使用 Scala 中的系统类加载器。
编辑:好的,我对此进行了更多研究,scala.bat 正在执行以下命令行(在纯 Windows 下,为了可读性而缩短)
java.exe -Xmx256M -Xms32M -Dscala.home="xxx" -cp "libsfromscalahome" scala.tools.nsc.MainGenericRunner -cp /temp Test
因此,命令行中的 -cp 选项仅作为选项传递给 MainGenericRunner,not爪哇。我相信,通过查看代码,在 unix 下,您可以为 scala 指定 -toolcp 选项,以获取包含在 java 类路径中的内容。像这样的东西(完全未经测试):
$ scala -toolcp /temp Test
此选项在 scala.bat 中不可用。这意味着如果您在 Windows 下工作,则必须使用以下方式获取资源
println(this.getClass.getClassLoader.getResource("toto"))
我在中找不到问题Scala 语言问题,但如果这对您来说是个问题,请提出问题并提交修复。我相信他们会很兴奋:-)
编辑:我已将此作为问题提出SI 5062 -toolcp 应该在 Windows 上可用,位于 scala.bat 中,并在上提供了一个拉取请求github.