Skip to content

Commit fb1d416

Browse files
committed
regenerate site
1 parent 8cf0a59 commit fb1d416

File tree

3 files changed

+21
-7
lines changed

3 files changed

+21
-7
lines changed

articles/language/interop/index.html

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
<div id="page-header">
6262
<h2>Language: Java Interop</h2>
6363
</div>
64-
<ol class="toc"><li><a href="#what-version-of-clojure-does-this-guide-cover">What Version of Clojure Does This Guide Cover?</a></li><li><a href="#overview">Overview</a></li><li><a href="#imports">Imports</a></li><ol><li><a href="#automatic-imports-for-javalang">Automatic Imports For java.lang.*</a></li><li><a href="#inner-nested-classes">Inner (Nested) Classes</a></li></ol><li><a href="#how-to-instantiate-java-classes">How to Instantiate Java Classes</a></li><li><a href="#how-to-invoke-java-methods">How to Invoke Java Methods</a></li><ol><li><a href="#instance-methods">Instance Methods</a></li><li><a href="#static-methods">Static Methods</a></li><li><a href="#chained-calls-with-the-double-dot-form">Chained Calls With The Double Dot Form</a></li><li><a href="#multiple-calls-on-the-same-object">Multiple Calls On the Same Object</a></li></ol><li><a href="#how-to-access-java-fields">How to Access Java Fields</a></li><li><a href="#how-to-set-java-fields">How to Set Java Fields</a></li><li><a href="#how-to-work-with-enums">How To Work With Enums</a></li><li><a href="#determining-classes-of-java-objects">Determining Classes of Java Objects</a></li><li><a href="#how-to-get-a-java-class-reference-by-name">How To Get a Java Class Reference By Name</a></li><ol><li><a href="#array-types-primitives">Array Types, Primitives</a></li></ol><li><a href="#implementing-java-interfaces-with-reify">Implementing Java Interfaces With reify</a></li><ol><li><a href="#reify-parameter-destructuring-and-varargs">reify, Parameter Destructuring and Varargs</a></li><li><a href="#example-1">Example 1</a></li></ol><li><a href="#extending-java-classes-with-proxy">Extending Java Classes With proxy</a></li><li><a href="#consuming-java-streams">Consuming Java Streams</a></li><li><a href="#clojure-functions-implement-runnable-and-callable">Clojure Functions Implement Runnable and Callable</a></li><li><a href="#gen-class-and-how-to-implement-java-classes-in-clojure">gen-class and How to Implement Java Classes in Clojure</a></li><ol><li><a href="#overview-1">Overview</a></li><li><a href="#aot">AOT</a></li><li><a href="#class-definition-with-clojurecoregen-class">Class Definition With clojure.core/gen-class</a></li><li><a href="#gen-class-in-the-ns-macro">gen-class In The ns Macro</a></li><li><a href="#examples">Examples</a></li><li><a href="#inspecting-class-signatures">Inspecting Class Signatures</a></li></ol><li><a href="#how-to-extend-protocols-to-java-classes">How To Extend Protocols to Java Classes</a></li><li><a href="#using-intrinsic-locks-synchronized-in-clojure">Using Intrinsic Locks ("synchronized") in Clojure</a></li><li><a href="#wrapping-up">Wrapping Up</a></li><li><a href="#contributors">Contributors</a></li></ol>
64+
<ol class="toc"><li><a href="#what-version-of-clojure-does-this-guide-cover">What Version of Clojure Does This Guide Cover?</a></li><li><a href="#overview">Overview</a></li><li><a href="#imports">Imports</a></li><ol><li><a href="#automatic-imports-for-javalang">Automatic Imports For java.lang.*</a></li><li><a href="#inner-nested-classes">Inner (Nested) Classes</a></li></ol><li><a href="#how-to-instantiate-java-classes">How to Instantiate Java Classes</a></li><li><a href="#how-to-invoke-java-methods">How to Invoke Java Methods</a></li><ol><li><a href="#instance-methods">Instance Methods</a></li><li><a href="#static-methods">Static Methods</a></li><li><a href="#chained-calls-with-the-double-dot-form">Chained Calls With The Double Dot Form</a></li><li><a href="#multiple-calls-on-the-same-object">Multiple Calls On the Same Object</a></li></ol><li><a href="#how-to-access-java-fields">How to Access Java Fields</a></li><li><a href="#how-to-set-java-fields">How to Set Java Fields</a></li><li><a href="#how-to-work-with-enums">How To Work With Enums</a></li><li><a href="#determining-classes-of-java-objects">Determining Classes of Java Objects</a></li><li><a href="#how-to-get-a-java-class-reference-by-name">How To Get a Java Class Reference By Name</a></li><ol><li><a href="#array-types-primitives">Array Types, Primitives</a></li></ol><li><a href="#implementing-java-interfaces-with-reify">Implementing Java Interfaces With reify</a></li><ol><li><a href="#functional-interface">Functional Interface</a></li><li><a href="#reify-parameter-destructuring-and-varargs">reify, Parameter Destructuring and Varargs</a></li><ol><li><a href="#example-reify">Example: reify</a></li><li><a href="#example-functional-interface">Example: Functional Interface</a></li><li><a href="#example-supplier">Example: Supplier</a></li></ol></ol><li><a href="#extending-java-classes-with-proxy">Extending Java Classes With proxy</a></li><li><a href="#consuming-java-streams">Consuming Java Streams</a></li><li><a href="#clojure-functions-implement-runnable-and-callable">Clojure Functions Implement Runnable and Callable</a></li><li><a href="#gen-class-and-how-to-implement-java-classes-in-clojure">gen-class and How to Implement Java Classes in Clojure</a></li><ol><li><a href="#overview-1">Overview</a></li><li><a href="#aot">AOT</a></li><li><a href="#class-definition-with-clojurecoregen-class">Class Definition With clojure.core/gen-class</a></li><li><a href="#gen-class-in-the-ns-macro">gen-class In The ns Macro</a></li><li><a href="#examples">Examples</a></li><li><a href="#inspecting-class-signatures">Inspecting Class Signatures</a></li></ol><li><a href="#how-to-extend-protocols-to-java-classes">How To Extend Protocols to Java Classes</a></li><li><a href="#using-intrinsic-locks-synchronized-in-clojure">Using Intrinsic Locks ("synchronized") in Clojure</a></li><li><a href="#wrapping-up">Wrapping Up</a></li><li><a href="#contributors">Contributors</a></li></ol>
6565
<p>This guide covers:</p><ul><li>How to instantiate Java classes</li><li>How to invoke Java methods</li><li>How to extend Java classes with proxy</li><li>How to implement Java interfaces with reify</li><li>How to generate Java classes with gen-class</li><li>Other topics related to interop</li></ul><p>This guide does not cover how to include Java files in Clojure projects.
6666
For that, head to <a href="/articles/cookbooks/cli_build_projects/#including-java-code-in-a-clojure-project">including Java code in a Clojure project</a></p><p>This work is licensed under a <a rel="license" href="https://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>
6767
(including images &amp; stylesheets). The source is available <a href="https://github.com/clojure-doc/clojure-doc.github.io">on Github</a>.</p><h2 id="what-version-of-clojure-does-this-guide-cover">What Version of Clojure Does This Guide Cover?</h2><p>This guide covers Clojure 1.12.</p><h2 id="overview">Overview</h2><p>Clojure was designed to be a hosted language that directly interoperates with its host platform (JVM, JS, CLR and so on).
@@ -251,7 +251,7 @@ <h2>Language: Java Interop</h2>
251251
(accept [this dir]
252252
true))]
253253
(instance? java.io.FileFilter ff)) ; ⇒ true
254-
</code></pre><p>In Clojure 1.12, a Java interface that is declared <code>@FunctionalInterface</code> can
254+
</code></pre><h3 id="functional-interface">Functional Interface</h3><p>In Clojure 1.12, a Java interface that is declared <code>@FunctionalInterface</code> can
255255
be inferred from from the context and can be satisfied with a regular Clojure
256256
function. <code>java.io.FilenameFilter</code> is such an interface, so you can pass a
257257
Clojure function directly to a Java method that expects a <code>FilenameFilter</code>:</p><pre><code class="clojure">(seq (.list (java.io.File. ".") #(str/starts-with? %2 ".")))
@@ -267,7 +267,7 @@ <h2>Language: Java Interop</h2>
267267
(comment ...)))
268268
</code></pre><p>This will compile without error but when called, the first argument to
269269
<code>accept</code> -- the directory object -- will be bound to <code>&amp;</code> and the second
270-
argument to <code>accept</code> -- the filename string -- will be bound to <code>more</code>.</p><h3 id="example-1">Example 1</h3><p>The following example demonstrates how instances created with <code>reify</code> are passed around
270+
argument to <code>accept</code> -- the filename string -- will be bound to <code>more</code>.</p><h4 id="example-reify">Example: reify</h4><p>The following example demonstrates how instances created with <code>reify</code> are passed around
271271
as regular Java objects:</p><pre><code class="clojure">(require '[clojure.string :as str])
272272
(import java.io.File)
273273

@@ -290,15 +290,29 @@ <h2>Language: Java Interop</h2>
290290
dir (File. "/home/sean/oss/clojure-doc.github.io/")]
291291
(into [] (.listFiles dir ff)))
292292
;; ⇒ [#object[java.io.File 0x5d512ddb "/home/sean/oss/clojure-doc.github.io/deps.edn"]]
293-
</code></pre><p>As above, in Clojure 1.12, because <code>java.io.FilenameFilter</code> is a functional interface, you can pass a Clojure function directly:</p><pre><code class="clojure">(import java.io.File)
293+
</code></pre><h4 id="example-functional-interface">Example: Functional Interface</h4><p>As above, in Clojure 1.12, because <code>java.io.FilenameFilter</code> is a functional interface, you can pass a Clojure function directly:</p><pre><code class="clojure">(import java.io.File)
294294

295295
;; a file filter implementation that keeps only .edn files
296296
(let [^java.io.FilenameFilter
297297
f (fn [_dir name]
298298
(str/ends-with? name ".edn"))
299299
dir (File. "/home/sean/oss/clojure-doc.github.io/")]
300300
(into [] (.listFiles dir f)))
301-
</code></pre><blockquote><p>Note: we need the type hint on <code>f</code> here because <code>.listFiles</code> has multiple overloads for the same arity, and we need to distinguish a <code>FilenameFilter</code> from a <code>FileFilter</code>.</p></blockquote><h2 id="extending-java-classes-with-proxy">Extending Java Classes With proxy</h2><p><code>proxy</code> is one of two ways to generate instances of anonymous classes in Clojure.
301+
</code></pre><blockquote><p>Note: we need the type hint on <code>f</code> here because <code>.listFiles</code> has multiple overloads for the same arity, and we need to distinguish a <code>FilenameFilter</code> from a <code>FileFilter</code>.</p></blockquote><h4 id="example-supplier">Example: Supplier</h4><p>Another change in Clojure 1.12 was to implement the
302+
<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/function/Supplier.html">Supplier Functional Interface</a>
303+
for Clojure derefable types (<code>delay</code>, <code>future</code>, <code>atom</code>, etc). Prior to Clojure
304+
1.12, you would have to use <code>reify</code> to adapt these Clojure types, when passing
305+
such objects to Java methods that expect a <code>Supplier</code>. For example,
306+
<a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.logging/java/util/logging/Logger.html#log(java.util.logging.Level,java.util.function.Supplier)"><code>java.util.logging.Logger/.log</code></a>:</p><pre><code class="clojure">user=&gt; (import '(java.util.logging Level Logger))
307+
java.util.logging.Logger
308+
user=&gt; (def logger (Logger/getLogger (str *ns*)))
309+
#'user/logger
310+
user=&gt; (.log logger Level/INFO (delay (str "Compute " "Me!")))
311+
Jun 07, 2025 9:01:47 PM clojure.lang.Reflector invokeMatchingMethod
312+
INFO: Compute Me!
313+
</code></pre><p>The <code>Supplier</code> object is only dereferenced if the log message is actually
314+
produced (i.e., the log level is high enough to log the message), so this can
315+
be useful for deferring expensive computations until they are actually needed.</p><h2 id="extending-java-classes-with-proxy">Extending Java Classes With proxy</h2><p><code>proxy</code> is one of two ways to generate instances of anonymous classes in Clojure.
302316
<code>proxy</code> takes two vectors: one listing its superclass and (optional) interfaces, the other listing constructor signatures, as well as
303317
zero or more
304318
method implementations. Method implementations are identical to <code>reify</code> except that the <code>this</code> argument is

cryogen.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<?xml version='1.0' encoding='UTF-8'?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><atom:link href="https://clojure-doc.org/" rel="self" type="application/rss+xml"/><title>Clojure Guides</title><link>https://clojure-doc.org/</link><description>Clojure Documentation</description><lastBuildDate>Sun, 08 Jun 2025 13:59:21 -0400</lastBuildDate><generator>clj-rss</generator></channel></rss>
1+
<?xml version='1.0' encoding='UTF-8'?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><atom:link href="https://clojure-doc.org/" rel="self" type="application/rss+xml"/><title>Clojure Guides</title><link>https://clojure-doc.org/</link><description>Clojure Documentation</description><lastBuildDate>Sun, 08 Jun 2025 14:13:02 -0400</lastBuildDate><generator>clj-rss</generator></channel></rss>

feed.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<?xml version='1.0' encoding='UTF-8'?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><atom:link href="https://clojure-doc.org/" rel="self" type="application/rss+xml"/><title>Clojure Guides</title><link>https://clojure-doc.org/</link><description>Clojure Documentation</description><lastBuildDate>Sun, 08 Jun 2025 13:59:21 -0400</lastBuildDate><generator>clj-rss</generator></channel></rss>
1+
<?xml version='1.0' encoding='UTF-8'?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><atom:link href="https://clojure-doc.org/" rel="self" type="application/rss+xml"/><title>Clojure Guides</title><link>https://clojure-doc.org/</link><description>Clojure Documentation</description><lastBuildDate>Sun, 08 Jun 2025 14:13:02 -0400</lastBuildDate><generator>clj-rss</generator></channel></rss>

0 commit comments

Comments
 (0)