Clojure is not “Java with different syntax,” but it is also not a foreign runtime. It is a JVM language that can use the entire Java ecosystem when it makes sense.
This chapter shows how to call Java code, create objects, implement interfaces, and work with common Java types. More importantly, it teaches boundary design: keep interop localized so most of your code stays idiomatic Clojure and easy to test.
For Java engineers, think of this as building adapters: treat Java APIs as an edge you integrate with, not the center of your Clojure program.
In this section
-
Calling Java Methods from Clojure
Interop call forms (`.`, `Class/staticMethod`) and how to avoid reflection surprises.
-
Creating Java Objects
Construct Java objects and configure them cleanly (often with doto) at interop boundaries.
-
Implementing Interfaces and Extending Classes
Use reify/proxy when a Java API needs an object callback or interface implementation.
-
Handling Java Exceptions
Use try/catch/finally for Java interop and wrap errors with ex-info when helpful.
-
Accessing Java Libraries
Add Maven dependencies and use Java libraries from Clojure without turning your code into Java-in-Lisp.
-
Integrating Clojure Code in Java Applications
Call Clojure from Java safely by treating namespaces as a stable API boundary.
-
Data Type Conversion Between Java and Clojure
Convert collections, null/nil, numbers, arrays, and common Java types at the boundary.
-
Primitive Types and Wrappers: Understanding Clojure and Java Interoperability
Explore how Clojure handles Java primitive types and their wrapper classes, including automatic boxing and unboxing, and ensuring correct type usage.
-
Java Collections Interoperability in Clojure: Conversion Techniques and Best Practices
Explore seamless conversion between Java collections and Clojure collections, enhancing interoperability and leveraging the strengths of both languages.
-
Handling Arrays in Clojure: Java Interoperability and Beyond
Explore how to handle Java arrays in Clojure, including creation, access, and modification. Learn about functions like make-array, to-array, and aget, and understand the nuances of Java-Clojure interoperability.
-
Handling `null` Values in Clojure: A Guide for Java Developers
Explore how Clojure represents Java's `null` as `nil`, and learn strategies for handling `nil` safely in your Clojure applications.
-
Performance Considerations in Interop
Keep interop out of hot loops, avoid reflection, and measure before optimizing.
-
Case Studies and Examples
See interop patterns applied to real JVM libraries: adapters, boundaries, and testing strategy.
-
Best Practices for Interoperability
Design the boundary: isolate Java types, handle nulls, avoid reflection, and keep the core idiomatic.