为什么 (int 10) 会产生一个 Long 实例?

13
为什么 (int 10) 不会产生一个 java.lang.Integer 类型的实例?
; why Long here?
=> (type (int 10))
; java.lang.Long

; this one is also Long, why not java.lang.Number?
=> (type (num 10))
; java.lang.Long

=> (type (double 10))
; java.lang.Double
=> (type (long 10))
; java.lang.Long
=> (type (float 10))
; java.lang.Float
=> (type (short 10))
; java.lang.Short
=> (type (bigint 10))
; clojure.lang.BigInt
=> (type (bigdec 10))
; java.math.BigDecimal
=> (type (boolean 10))
; java.lang.Boolean
=> (type (char 10))
; java.lang.Character
=> (type (byte 10))
; java.lang.Byte

它在Clojure 1.5中得到了修复:http://dev.clojure.org/jira/browse/CLJ-820 我在Clojure 1.6中进行了测试,(type (int 10)) 返回java.lang.Integer。 - Grzegorz Luczywo
2个回答

17

Clojure内部只处理long整数。使用(int)long强制转换为int,以便调用期望int参数的Java方法。

在这种情况下,(int 10)确实返回Java的int,但Clojure随后将int提升回long(type)使用(class)查找其参数的类型(在本例中),因此long被包装为java.lang.Long

您可以使用java.lang.Integer的构造函数或工厂方法之一来生成java.lang.Integer

user> (type (Integer. 10))
java.lang.Integer

user> (type (Integer/valueOf 10))
java.lang.Integer

user> (type (Integer/decode "10"))
java.lang.Integer

...

(num)将把它的参数向上转型为抽象类java.lang.Number,但(type)将返回其参数的实际类型,即再次返回java.lang.Long


7

int 是一种用于互操作调用的原始整数转换。由于每个类型调用都需要一个 Object,因此这些东西会再次被装箱,而Clojure(> = 1.3)会将其装箱为 LongDouble。如果您需要一个 Integer,则必须创建一个。

user=> (type (Integer/valueOf 10))
java.lang.Integer

为什么 (.compareTo (Integer. 10) (int 10)) 的结果是 ClassCastException java.lang.Long cannot be cast to java.lang.Integer?这不是 Java 互操作的一个例子吗? - Eric Schoonover
.compareTo 接收 Object 类型,因此 (int 10) 的结果会立即打包回 Long,导致在 compareTo 中尝试将其转换为 Integer 时出现异常。这是 Clojure 打包和 Java 中诸如 java.lang.Comparable 的泛型不具有实体化的良好互动。 - Dave Ray
3
= 1.3 是不正确的:这种令人困惑的行为已在1.4中恢复。
- amalloy
1
@amalloy,1.4版本的行为是什么?(int)会产生一个Integer吗? - Eric Schoonover
1
@spoon16 是的,它可以。但不要只听我的话:试一试吧! - amalloy
显示剩余2条评论

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