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

JVM如何区分Scala字节码和Java字节码?,java,scala,jvm,bytecode,Java,Scala,Jvm,Bytecode,因为Scala还生成字节码并由JVM执行。我想知道JVM如何区分Scala字节码和Java字节码。谁能解释一下吗 Scalac Myprogram.scala java Myprogram 所以这句话很好?不好。Scala编译成与Java相同的字节码。scalac和javac都生成字节码。JVM不关心字节码是如何产生的,对JVM来说都是一样的 但是,scala和java以不同的方式设置启动类路径,因此如果代码包含scala运行时库调用,并且很可能包含,则需要由scala运行,而不是java

因为Scala还生成字节码并由JVM执行。我想知道JVM如何区分Scala字节码和Java字节码。谁能解释一下吗

 Scalac Myprogram.scala
 java Myprogram

所以这句话很好?

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

scalac和
javac
都生成字节码。JVM不关心字节码是如何产生的,对JVM来说都是一样的

但是,
scala
java
以不同的方式设置启动类路径,因此如果代码包含scala运行时库调用,并且很可能包含,则需要由
scala
运行,而不是
java


如果必须的话,您可以使用
java
手动设置引导类路径,但是当
scala
可以帮您完成这些额外的工作时,为什么还要进行这些工作呢?

scala编译成普通的java字节码,所以JVM看起来没有什么区别。Java没有的Scala的额外特性是通过编译时过程和运行时帮助函数的组合来实现的。如果您反汇编生成的Scala类,您可能会看到大量对Scala运行时的调用,例如装箱和取消装箱参数

我想知道JVM如何区分Scala字节码和Java字节码

没有。没有Scala字节码这样的东西。Scala编译器编译成JVM字节码。就像Java编译器也编译成JVM字节码一样

JVM对Scala一无所知。它也对Java一无所知。它也不知道Groovy、Clojure、Kotlin、Ceylon、Fantom、Ruby、Python、ECMAScript或JVM上实现的任何其他400种编程语言

JVM只知道一种语言:JVM字节码


请注意,这实际上与任何其他机器(虚拟机或非虚拟机)没有什么不同。CLR只知道CIL,对C#、VB.NET或F#一无所知。英特尔核心CPU只知道AMD64和x86机器代码,它对C、C++、Objto-C、SWIFT、GO、java、Python一无所知。cpythonvm只知道CPython字节码,对Python一无所知。

一张图片抵得上千言万语


从执行者的角度来看,标准中定义的字节码是相同的。但是,当您使用调试器时,需要更多信息来匹配正确的语言和源文件

指示生成JVM字节码的源代码是什么的唯一方法是通过可选的类属性
SourceFile
(来自Java 1.0.2)和
SourceDebugExtension
(来自Java 5.0)。 和11

附加信息将给出源
LineNumberTable
中各种对象的行号,这也是可选的。

您可以找到其他JVM规范的等效规范

IDE使用这些值来获取JVM类的上下文,但它们是可选值,调试信息取决于编译器

因此,它可以是一个了解编译器是什么的信息,但你不能依赖它作为确定信息。如果定义了它,它应该在编译器定义中

使用scalac,您可以使用-g选项切换信息存储,与javac相同,只是
notc
,因为Java不管理TCO:

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

默认情况下,

要获取类加载器以从类文件检索信息,可以使用开源库ASM:


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

JVM只看到字节码。它的行为没有什么不同。那么,我们可以对scala和java使用相同的JVM吗…?scala和java都不能使用JVM。您只能将JVM用于JVM字节码。JVM对Scala一无所知。JVM对Java一无所知。它唯一能理解的就是JVM字节码。