Unless you really need to eliminate all reflection for some reason, the easiest answer is to put this line in your project.clj
:
:global-vars {*warn-on-reflection* false}
I could not get the type hint to eliminate the warning when using an empty Clojure map as a constructor arg. Observe this code:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(dotest
(newline)
(spyxx {:a 1}) ; `spyxx` prints expression, type, and value
(newline)
(spyxx (java.util.HashMap.)) ; Works
(spyxx (new java.util.HashMap)) ; Works
(newline)
(let [m ^java.util.Map {}]
(spyxx (new java.util.HashMap m)) ; Reflection Warning
(spyxx (java.util.HashMap. m))) ; Reflection Warning
(newline)
(let [^java.util.Map m {}]
(spyxx (new java.util.HashMap m)) ; Works
(spyxx (java.util.HashMap. m)))) ; Works
(def ^java.util.Map m3 {})
(dotest
(newline)
(spyxx m3)
(spyxx (java.util.HashMap. m3))) ; Works
with the following results. Note that all of them work, but you get a reflection warning where indicated above:
--------------------------------------
Clojure 1.10.2-alpha1 Java 15
--------------------------------------
Testing tst.demo.core
{:a 1} => <#clojure.lang.PersistentArrayMap {:a 1}>
(java.util.HashMap.) => <#java.util.HashMap {}>
(new java.util.HashMap) => <#java.util.HashMap {}>
(new java.util.HashMap m) => <#java.util.HashMap {}>
(java.util.HashMap. m) => <#java.util.HashMap {}>
(new java.util.HashMap m) => <#java.util.HashMap {}>
(java.util.HashMap. m) => <#java.util.HashMap {}>
m3 => <#clojure.lang.PersistentArrayMap {}>
(java.util.HashMap. m3) => <#java.util.HashMap {}>
It seems you don't need the empty Clojure map as a constructor arg, and then the problem goes away. You can also make the warning go away by setting *warn-on-reflection*
to false (either in project.clj
or manually in the code).
If you use a type hint, it is easy to get it in the wrong place where it will be silently ignored.
Update
Consider this extra code:
(dotest
(newline)
(set! *warn-on-reflection* false) ; not executed upon parsing
(let [m4 ^java.util.Map {}]
(spyxx (new java.util.HashMap m4)) ; Reflection Warning
(spyxx (java.util.HashMap. m4)))) ; Reflection Warning
(newline)
; vvv executed when parsed before following lines
(set! *warn-on-reflection* false)
(let [m5 ^java.util.Map {}]
(spyxx (new java.util.HashMap m5)) ; Works
(spyxx (java.util.HashMap. m5))) ; Works
The first test generates a reflection warning when parsed (before the test is run), since the parser seems to be evaluating constant expressions (speculation).
The 2nd test does not generate warnings, since Clojure is reading, parsing, and evaluating each form in turn. Thus the call to (set! *warn-on-reflection* false)
is executed to disable warnings before the following lines are read & evaluated.