JVM如何区分Scala字节码和Java字节码?

9

由于Scala也会产生字节码并由JVM执行,我想知道JVM如何区分Scala字节码和Java字节码。请问有人能解释一下吗?

 Scalac Myprogram.scala
 java Myprogram

那么这些语句是完全没问题的吗?


3
JVM 只能看到字节码,它不会表现出不同的行为。 - Peter Lawrey
6个回答

27
我想知道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#。Intel Core CPU只认识AMD64和x86机器码,它不知道C、C++、Objective-C、Swift、Go、Java、Python等等。CPython虚拟机只知道CPython字节码,它不知道Python。

那么,我们可以同时为Scala和Java使用相同的JVM吗? - Dilan
你不能同时为Scala或Java使用JVM,只能用于JVM字节码。JVM对Scala一无所知,也不了解Java。它唯一理解的是JVM字节码。 - Jörg W Mittag

10

不会。Scala编译成的字节码与Java相同。


5
一幅画胜过千言万语。

Scala Runtime

(图片展示Scala Runtime)

4
scalacjavac都能生成字节码,对于JVM而言,无论是哪种方式生成的字节码都是相同的。
但是,scalajava会以不同的方式设置引导CLASSPATH,所以如果你的代码包含Scala运行库调用(这很可能会有),它需要由scala而不是java运行。
如果你非常必须使用java手动设置引导CLASSPATH,那么你可以这样做,但是为什么要多做这么多工作呢?scala可以帮你完成这些工作。

1
Scala编译成普通的Java字节码,因此JVM看起来没有任何区别。Scala具有的Java没有的额外功能是通过编译时传递和运行时辅助函数的组合实现的。如果您反汇编生成的Scala类,您可能会看到大量调用Scala运行时的内容,例如装箱和取消装箱参数。

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相同,除了Java不管理TCO:notc

g:{none,source,line,vars,notc} “none”不生成调试信息, “source”仅生成源文件属性, “line”生成源和行号信息, “vars”生成源、行号和局部变量信息, “notc”生成所有上述信息,并且不执行尾调用优化。

默认情况下为line

要获取ClassLoader以从类文件中检索信息,可以使用开源库ASM:http://asm.ow2.org/

您还可以自己解析类文件或内部存储,检索类属性并不是很困难。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接