2012-02-26 7 views
12

¿Por qué (int 10) no produce una instancia del tipo java.lang.Integer?¿Por qué (int 10) produce una instancia Larga?

; 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 
+0

Se corrigió en Clojure 1.5: http://dev.clojure.org/jira/browse/CLJ-820 Lo probé en Clojure 1.6 y (tipo (int 10)) da java.lang.Integer. –

Respuesta

16

Clojure se ocupa solo de long enteros internamente. (int) se utiliza para emitir un long a int para llamar a métodos Java que esperan un argumento int.

En este caso (int 10) en efecto, devuelven un Java int, pero Clojure entonces promueve la int de nuevo a un long. (type) usa (class) para averiguar el tipo de su argumento (en este caso) y, por lo tanto, el long se coloca en un java.lang.Long.

Puede producir java.lang.Integer mediante el uso de uno de los java.lang.Integer constructores o métodos de fábrica:

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

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

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

... 

(num) se upcast su argumento a la clase abstracta java.lang.Number, pero (type) volverá el tipo real de su argumento, es decir java.lang.Long de nuevo.

7

int es una conversión a número entero primitiva para las llamadas de interoperabilidad. Dado que cada una de las llamadas de tipo toma un Object, las cosas se vuelven a empaquetar y Clojure (> = 1.3) las cajas a Long y Double. Si necesita un Integer, debe crear uno.

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

¿Por qué '(.compareTo (Integer.10) (int 10))' da como resultado 'ClassCastException java.lang.Long no se puede convertir a java.lang.Integer'? ¿No es este un ejemplo de interoperabilidad de Java? –

+0

'.compareTo' toma' Object', por lo que el resultado de '(int 10)' se coloca de inmediato en un recuadro 'Long', lo que da como resultado la excepción dentro de 'compareTo' cuando intenta convertir a' Integer'. Es una buena interacción entre el boxeo de Clojure y el hecho de que los genéricos como 'java.lang.Comparable' en Java no se reifican. –

+0

@DaveRay De acuerdo con http://docs.oracle.com/javase/6/docs/api/java/lang/Integer.html 'compareTo' toma un' Integer', que deriva de 'Object'. ¿Es correcto decir que '(int)' solo debe usarse cuando se requiere una instancia 'int', no funciona cuando se necesita una instancia' Integer'. –

Cuestiones relacionadas