2012-02-26 11 views
12

Perché (int 10) non produce un'istanza di tipo java.lang.Integer?Perché (int 10) produce un'istanza lunga?

; 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

È stato corretto in Clojure 1.5: http://dev.clojure.org/jira/browse/CLJ-820 L'ho testato in Clojure 1.6 e (tipo (int 10)) fornisce java.lang.Integer. –

risposta

16

Clojure si occupa solo di numeri interi long internamente. (int) viene utilizzato per trasmettere uno long a int per chiamare metodi Java che prevedono un argomento int.

In questo caso (int 10) effettivamente restituiscono un Java int, ma Clojure poi promuove la int di nuovo ad un long. (type) utilizza (class) per trovare il tipo del suo argomento (in questo caso), e pertanto lo long viene inserito in un numero java.lang.Long.

È possibile produrre java.lang.Integer utilizzando uno dei java.lang.Integer costruttori o metodi di fabbrica:

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

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

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

... 

(num) sarà upcast suo argomento alla classe astratta java.lang.Number, ma (type) tornerà il tipo effettivo della sua tesi, cioè java.lang.Long ancora.

7

int è un numero intero cast primitiva per le chiamate di interoperabilità. Dal momento che ciascuna delle chiamate di tipo prende un Object le cose vengono riqualificate di nuovo e le caselle Clojure (> = 1.3) a Long e Double. Se hai bisogno di un Integer devi crearne uno.

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

Quindi perché '(.compareTo (Integer. 10) (int 10))' risulta in 'ClassCastException java.lang.Long non può essere lanciato su java.lang.Integer'? Non è un esempio di interoperabilità Java? –

+0

'.compareTo' prende' Object', quindi il risultato di '(int 10)' viene immediatamente ricondotto ad un 'Long' risultante nell'eccezione all'interno di' compareTo' quando tenta di eseguire il cast su 'Integer'. È una bella interazione tra la boxe di Clojure e il fatto che i generici come 'java.lang.Comparable' in Java non sono reificati. –

+0

@DaveRay Secondo http://docs.oracle.com/javase/6/docs/api/java/lang/Integer.html 'compareTo' prende un' Integer', che deriva da 'Object'. È corretto dire che '(int)' dovrebbe essere usato solo quando è richiesta un'istanza 'int', non funziona quando è necessaria un'istanza' Integer'. –

Problemi correlati