Macros expand code at compile time; reflection discovers types/members at runtime.
Macros and Java reflection both feel “dynamic,” but they operate at different times.
This matters for Java interop: Clojure can use reflection when it cannot infer a method call target (for example, when there are no type hints). That is a runtime cost, and it is solved with better type information—not with macros.