2012-02-26 12 views
12

Dlaczego (int 10) nie produkuje wystąpienia typu java.lang.Integer?Dlaczego (int 10) powoduje wystąpienie Long?

; 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

Zostało to naprawione w Clojure 1.5: http://dev.clojure.org/jira/browse/CLJ-820 Przetestowałem to w Clojure 1.6 i (type (int 10)) daje java.lang.Integer. –

Odpowiedz

16

Clojure wewnętrznie obsługuje tylko long liczb całkowitych. (int) służy do przesyłania long do int w celu wywoływania metod Java, które oczekują argumentu int.

W tym przypadku (int 10) rzeczywiście zwrócić Java int, ale Clojure następnie promuje int powrotem do long. (type) używa (class), aby znaleźć typ argumentu (w tym przypadku), a zatem long zostaje zapakowany do java.lang.Long.

Można produkować java.lang.Integer stosując jedną z java.lang.Integer konstruktorów i metod fabrycznych:

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

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

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

... 

(num) zostanie wyrzucony w górę swój argument do klasy abstrakcyjnej java.lang.Number, ale (type) powróci rzeczywisty typ jego argumentu, czyli java.lang.Long jeszcze raz.

7

int jest obsada do pierwotnej liczby całkowitej dla połączeń międzyoperacyjnych. Ponieważ każda z wywołań typu pobiera Object rzeczy stają się ponownie zapakowane, a pola Clojure (> = 1.3) to Long i Double. Jeśli potrzebujesz Integer, musisz go utworzyć.

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

Dlaczego więc '(.compareTo (Integer.10) (int 10))' powoduje 'ClassCastException java.lang.Long nie można rzutować na java.lang.Integer'? Czy to nie jest przykład interakcji Java? –

+0

'.compareTo' pobiera' Object', więc wynik '(int 10)' jest od razu zapakowany z powrotem do 'Long', powodując wyjątek wewnątrz' compareTo' przy próbie rzutowania na 'Integer'. To miła interakcja pomiędzy boksem Clojure'a a faktem, że generics jak 'java.lang.Comparable' w Javie nie są reifikowane. –

+0

@DaveRay Według http://docs.oracle.com/javase/6/docs/api/java/lang/Integer.html 'compareTo' pobiera" Integer ", który pochodzi od' Object'. Czy słusznie jest powiedzieć, że '(int)' powinno być używane tylko wtedy, gdy instancja 'int' jest wymagana, nie działa, gdy potrzebna jest instancja' Integer'. –

Powiązane problemy