gpt4 book ai didi

java - Scala:直接或通过包装器访问 Java 原语?

转载 作者:行者123 更新时间:2023-11-29 07:32:51 29 4
gpt4 key购买 nike

我知道您可以直接从 Scala 访问 java 原语

val javaDouble = new java.lang.Double(1.0)

这是否意味着我们正在通过包装器直接访问原语?语法 new java.lang.Double(1.0) 看起来像是在创建一个新对象,因此有一个包装器可以让我们访问 java 原语。如果这是真的,我想知道它需要多少额外的内存占用和计算。

最佳答案

你说“我知道你可以直接访问 Java 原语”,然后紧接着举了一个不是 Java 原语而是用于封装原语的 Java 类的例子。

Scala 可以访问未装箱的原语——字符串的 length 方法,例如:

scala> val l = "fish".length
l: Int = 4

这是一个普通的Int(Java 中的int)。看不到拳击。

Scala 还可以访问 Java 版本的盒装原语。

scala> val boxed = new java.lang.Integer(2)
boxed: Integer = 2

scala> val isJavaObject = boxed.isInstanceOf[Object]
isJavaObject: Boolean = true

使用泛型时,基元会根据需要透明地装箱和拆箱(类似于它在 Java 中的工作方式,但更全面一些)。它会跟踪您是否需要原语,因此看起来一切都“正常工作”。

scala> def ident[A](a: A): A = a
ident: [A](a: A)A

scala> def lAgain = ident(l)
lAgain: Int

scala> def boxedAgain = ident(boxed)
boxedAgain: Integer

但是,如果您开始进行模式匹配,您会发现这种错觉只是表面现象:Int 在各种类型中被装箱到 java.lang.Integer上下文(泛型或转换为 Any),因为这是 JVM 的要求。

scala> def isInt(a: Any) = a match { case i: Int => true; case _ => false }
isInt: (a: Any)Boolean

scala> val test = (isInt(l), isInt(boxed))
test: (Boolean, Boolean) = (true,true)

scala> def isBoxedInt(a: Any) = a match { case _: java.lang.Integer => true; case _ => false }
isBoxedInt: (a: Any)Boolean

scala> val test2 = (isBoxedInt(l), isBoxedInt(boxed))
test2: (Boolean, Boolean) = (true,true)

因此,只要编译器知道正确的类型,它就会尽可能将原语用作原语,并在没有时将它们透明地装箱。如果您忘记了类型并使用模式匹配来尝试找出其中的内容,它将提取您要求的任何版本。 (当它需要自动执行此操作时,例如在相等的情况下,它会假定装箱原语应该像原语一样工作。)

关于java - Scala:直接或通过包装器访问 Java 原语?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39665760/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com