答案 0 :(得分:19)
我想知道JVM如何区分Scala字节码和Java字节码。
没有。没有Scala字节码这样的东西。 Scala编译器编译为JVM字节码。就像Java编译器也编译为JVM字节码一样。
JVM对Scala一无所知。它对Java也一无所知。它也不知道有关Groovy,Clojure,Kotlin,Ceylon,Fantom,Ruby,Python,ECMAScript或任何其他~400种JVM上实现的编程语言。
JVM只知道一种语言:JVM字节码。
请注意,这与任何其他计算机(虚拟或非虚拟机)没有什么不同。 CLR只知道CIL,它对C#,VB.NET或F#一无所知。英特尔酷睿CPU只知道AMD64和x86机器代码,它对C,C ++,Objective-C,Swift,Go,Java,Python一无所知。 CPython VM只知道CPython字节码,它对Python一无所知。
答案 1 :(得分:10)
没有。 Scala编译为与Java相同的字节码。
答案 2 :(得分:4)
scalac
和javac
都生成字节码。 JVM并不关心字节码是如何产生的,它与JVM完全相同。
但是,scala
和java
以不同的方式设置引导CLASSPATH,因此如果您的代码包含Scala运行时库调用,并且很可能,则需要scala
运行,而不是java
。
可以手动使用java
手动设置启动CLASSPATH,如果您必须这样做,但为什么要完成所有额外工作,scala
将为您执行此操作?
答案 3 :(得分:4)
答案 4 :(得分:1)
Scala编译为普通的Java字节码,因此JVM似乎没有任何区别。 Java所具有的Scala的额外功能是通过编译时传递和运行时辅助函数的组合来实现的。如果你反汇编生成的Scala类,你可能会看到很多对Scala运行时的调用,例如装箱和拆箱参数。
答案 5 :(得分:0)
标准中定义的字节代码在执行程序的角度是相同的。但是当您使用调试器时,需要更多信息来匹配正确的语言和源文件。
指示生成JVM字节码的源代码的唯一方法是通过可选的类属性SourceFile
(来自Java 1.0.2)和SourceDebugExtension
(来自Java 5.0)。
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.10和11
附加信息将给出源LineNumberTable
中各种对象的行号,这也是可选的。
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.12
您可以找到其他JVM规范的等效项。
IDE使用它们来获取JVM类的上下文,但它们是可选值,调试信息取决于编译器。
所以它可以是一个知道编译器是什么的信息,但你不能依赖它作为确定的信息。如果已定义,则应该在编译器定义中。
使用scalac,您可以使用-g选项切换信息存储,与javac相同,但notc
除外,因为Java不管理TCO:
g:{none,source,line,vars,notc}
"none" generates no debugging info,
"source" generates only the source file attribute,
"line" generates source and line number information,
"vars" generates source, line number and local variable information,
"notc" generates all of the above and will not perform tail call optimization.
默认情况下line
要让ClassLoader从类文件中检索信息,您可以使用开源库ASM:http://asm.ow2.org/
您也可以自己解析类文件或内部存储,检索类属性并不是很困难。