java - 为什么 Scala 偶尔会回退到 Java 对象?

标签 java scala language-interoperability

我几乎可以肯定以前有人问过这个问题,但我找不到合适的词来找到它。

scala> Seq[Any]( 3, 3.4 )
res0: Seq[Any] = List(3, 3.4)

scala> res0( 1 ).getClass
res1: Class[_] = class java.lang.Double

scala> Seq( 3, 3.4 )
res2: Seq[Double] = List(3.0, 3.4)

scala> res2( 1 ).getClass
res3: Class[Double] = double

为什么 Scala 将我的 Double 输入处理为 Seq[Any] 中的 java.lang.Double 但将其保持为 scala.Double 在使用 Seq[AnyRef] 时?有没有办法阻止这种行为,而是始终使用 Scala 类型?

最佳答案

Scala 的 Double 对应于 Java 的 double 但如果需要可能会自动装箱和拆箱,当它自动装箱时它会变成 java.lang.Double .实际上,集合需要自动装箱原始变量。

如果未明确声明类型,则根据分配给它们的值推断您声明的集合类型。问题中两个声明之间的区别在于,对于 Seq(value1,value2,...) 类型推断试图找到“最佳”类型,出现 Seq[Double] 然后基于此类型 (Scala Double) 解释 value1value2 等。如果您将类型显式声明为 Seq[Any],则不会运行类型推断(因为您自己指定了类型),因此值 value1value2 等不会被“强制”解释为固定类型。

由于 Seq 是一个集合,原始类型是不允许的,必须自动装箱,所以 Java 的 double 不能放入 while java.lang.Double 可以。试图隐藏 Seq[Double] 的装箱和拆箱并透明地交换原语和对象的逻辑没有发挥作用。实际上,在 Seq[Any] 中,每个元素可能属于不同类型,这意味着这种装箱和拆箱在一般情况下不起作用(在您的示例中,res0(0) .getClass 是一个 Integer,而 res2(0).getClass 是一个 Double。

因此,从本质上讲,如果您没有显式声明类型,类型推断就会开始并首先尝试为集合的所有元素找到一个通用类型,然后使用集合类型参数将所有元素转换为该类型明确指定,不会发生这样的事情,所有值的类型都被解释为“原始”。

关于java - 为什么 Scala 偶尔会回退到 Java 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18473877/

相关文章:

java - 使用java在数组中查找具有不同绝对值的数字

java - 从 Java 代码中看不到 Scala 案例类复制方法

scala - Scala中的映射类型

java - Groovy、Scala 可能让我的生活更轻松?

architecture - 语言互操作性的最佳实践是什么?

objective-c - 如何桥接一个以闭包为参数的函数到 objc

multithreading - 使用 fortran dll 的线程安全 C# 服务

java - 停止 JUNit 记录

java - Spring 启动。获取 bean 作为对本地 bean 方法调用的响应

java - 是否可以在 Guice 的范围末尾自动清理资源?