为什么 scalac 需要在需要 `Any` 的方法中装箱 `Int`
Why does scalac need to box an `Int` in a method expecting an `Any`
考虑以下 class:
package test
class Test {
def main(args: Array[String]): Unit = {
val i: Int = 0
println(i)
}
}
main
的字节码是:
public main([Ljava/lang/String;)V
// parameter final args
L0
LINENUMBER 4 L0
ICONST_0
L1
ISTORE 2
L2
LINENUMBER 5 L2
GETSTATIC scala/Predef$.MODULE$ : Lscala/Predef$;
ILOAD 2
INVOKESTATIC scala/runtime/BoxesRunTime.boxToInteger (I)Ljava/lang/Integer;
INVOKEVIRTUAL scala/Predef$.println (Ljava/lang/Object;)V
L3
RETURN
L4
LOCALVARIABLE i I L1 L3 2
LOCALVARIABLE this Ltest/Test; L0 L4 0
LOCALVARIABLE args [Ljava/lang/String; L0 L4 1
MAXSTACK = 2
MAXLOCALS = 3
可以看出,当我们调用 println
时,Int
被装箱到 java.lang.Integer
中。但是println
的签名是:
def println(x: Any): Unit
作为 Int <: AnyVal <: Any
,为什么 Int
需要在通话中被装箱?
Any
可以在 Scala 中按语法使用,因为编译器会根据需要自动装箱任何 Java 基本类型(Int
等同于这种类型)。从发出的字节代码中,您可以看到 INVOKEVIRTUAL
是在具有以下签名的方法上调用的:
scala/Predef$.println (Ljava/lang/Object;)V
由于 Java 中没有 Any
的概念,scalac 发出 Object
的方法签名,在 Scala 中等同于 AnyRef
。由于 Int
扩展了 AnyVal
,我们需要分配等效的 Java 包装器,即 Integer
.
考虑以下 class:
package test
class Test {
def main(args: Array[String]): Unit = {
val i: Int = 0
println(i)
}
}
main
的字节码是:
public main([Ljava/lang/String;)V
// parameter final args
L0
LINENUMBER 4 L0
ICONST_0
L1
ISTORE 2
L2
LINENUMBER 5 L2
GETSTATIC scala/Predef$.MODULE$ : Lscala/Predef$;
ILOAD 2
INVOKESTATIC scala/runtime/BoxesRunTime.boxToInteger (I)Ljava/lang/Integer;
INVOKEVIRTUAL scala/Predef$.println (Ljava/lang/Object;)V
L3
RETURN
L4
LOCALVARIABLE i I L1 L3 2
LOCALVARIABLE this Ltest/Test; L0 L4 0
LOCALVARIABLE args [Ljava/lang/String; L0 L4 1
MAXSTACK = 2
MAXLOCALS = 3
可以看出,当我们调用 println
时,Int
被装箱到 java.lang.Integer
中。但是println
的签名是:
def println(x: Any): Unit
作为 Int <: AnyVal <: Any
,为什么 Int
需要在通话中被装箱?
Any
可以在 Scala 中按语法使用,因为编译器会根据需要自动装箱任何 Java 基本类型(Int
等同于这种类型)。从发出的字节代码中,您可以看到 INVOKEVIRTUAL
是在具有以下签名的方法上调用的:
scala/Predef$.println (Ljava/lang/Object;)V
由于 Java 中没有 Any
的概念,scalac 发出 Object
的方法签名,在 Scala 中等同于 AnyRef
。由于 Int
扩展了 AnyVal
,我们需要分配等效的 Java 包装器,即 Integer
.