GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing clojure.org — Clojure - Java Interop Java Interop
Java InteropTable of Contents
Class accessClassname Symbols representing class names are resolved to the Class instance. Inner or nested classes are separated from their outer class with a A symbol whose ns-part names a class or a primitive, and whose name part is a single digit between 1 and 9, designates an array class of that component type and dimension. Added in 1.12.
Member access(.instanceMember instance args*)
The preferred idiomatic forms for accessing field or method members are given above. The instanceMember form works for both fields and methods. The instanceField form is required if both a field and a 0-argument method of the same name exist. Since Clojure 1.12, The unqualified "." forms expand into calls to the dot operator (described below) at macroexpansion time. The expansions are as follows:
Method valuesSince Clojure 1.12, programmers can use qualified methods as ordinary functions in value contexts - the compiler will automatically generate the wrapping function. When used as values, qualified methods supply only the class and method name, and thus cannot resolve overloaded methods. Therefore, the compiler will generate a reflective call when a qualified method does not resolve due to overloading. Developers can supply :param-tags metadata on qualified methods to specify the signature of a single desired method, 'resolving' it. The Dot special form(. instance-expr member-symbol) Special form. The '.' special form is the basis for access to Java. It can be considered a member-access operator, and/or read as 'in the scope of'. If the first operand is a symbol that resolves to a class name, the access is considered to be to a static member of the named class. Note that nested classes are named EnclosingClass$NestedClass, per the JVM spec. Otherwise it is presumed to be an instance member and the first argument is evaluated to produce the target object. For the special case of invoking an instance member on a Class instance, the first argument must be an expression that evaluates to the class instance - note that the preferred form at the top expands If the second operand is a symbol and no args are supplied it is taken to be a field access - the name of the field is the name of the symbol, and the value of the expression is the value of the field, unless there is a no argument public method of the same name, in which case it resolves to a call to the method. If the second operand is a symbol starting with -, the member-symbol will resolve only as field access (never as a 0-arity method) and should be preferred when that is the intent. If the second operand is a list, or args are supplied, it is taken to be a method call. The first element of the list must be a simple symbol, and the name of the method is the name of the symbol. The args, if any, are evaluated from left to right, and passed to the matching method, which is called, and its value returned. If the method has a void return type, the value of the expression will be nil. Note that placing the method name in a list with any args is optional in the canonic form, but can be useful to gather args in macros built upon the form. Note that boolean return values will be turned into Booleans, chars will become Characters, and numeric primitives will become Numbers unless they are immediately consumed by a method taking a primitive. The member access forms given at the top of this section are preferred for use in all cases other than in macros. (.. instance-expr member+) member ⇒ fieldName-symbol or (instanceMethodName-symbol args*) Macro. Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance:
expands to:
but is easier to write, read, and understand. See also the -> macro which can be used similarly:
(doto instance-expr (instanceMethodName-symbol args*)*) Macro. Evaluates instance-expr then calls all of the methods/functions with the supplied arguments in succession on the resulting object, returning it.
(Classname. args*) Special form. The args, if any, are evaluated from left to right, and passed to the constructor of the class named by Classname. The constructed object is returned. As shown, in addition to the canonic special form new, Clojure supports special macroexpansion of symbols containing '.':
can be written
the latter expanding into Since Clojure 1.12, a qualified form may also be used (it is not rewritten at macro expansion time):
Like methods, qualified constructors (instance? Class expr) Evaluates expr and tests if it is an instance of the class. Returns true or false (set! (. instance-expr instanceFieldName-symbol) expr) Assignment special form. When the first operand is a field member access form, the assignment is to the corresponding field. If it is an instance field, the instance expr will be evaluated, then the expr. In all cases the value of expr is returned. Note - you cannot assign to function params or local bindings. Only Java fields, Vars, Refs and Agents are mutable in Clojure. (memfn method-name arg-names*) Macro. Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn.
Note it is almost always preferable to do this directly now, with syntax like:
(bean obj) Takes a Java object and returns a read-only implementation of the map abstraction based upon its JavaBean properties.
Support for Java in Clojure Library FunctionsMany of the Clojure library functions have defined semantics for objects of Java types. contains? and get work on Java Maps, arrays, Strings, the latter two with integer keys. count works on Java Strings, Collections and arrays. nth works on Java Strings, Lists and arrays. seq works on Java reference arrays, Iterables and Strings. Since much of the rest of the library is built upon these functions, there is great support for using Java objects in Clojure algorithms. Implementing Interfaces and Extending ClassesClojure supports the dynamic creation of objects that implement one or more interfaces and/or extend a class with the proxy macro. The resulting objects are of an anonymous class. You can also generate statically-named classes and .class files with gen-class. As of Clojure 1.2, reify is also available for implementing interfaces. Java annotations may be attached to classes, constructors, and methods via metadata on (proxy [class-and-interfaces] [args] fs+) class-and-interfaces - a vector of class names Macro Expands to code which creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns. A single class, if provided, must be first. If not provided it defaults to Object. The interfaces names must be valid interface types. If a method fn is not provided for a class method, the superclass method will be called. If a method fn is not provided for an interface method, an UnsupportedOperationException will be thrown should it be called. Method fns are closures and can capture the environment in which proxy is called. Each method fn takes an additional implicit first arg, which is bound to this. Note that while method fns can be provided to override protected methods, they have no other access to protected members, nor to super, as these capabilities cannot be proxied. ArraysClojure supports the creation, reading and modification of Java arrays. It is recommended that you limit use of arrays to interop with Java libraries that require them as arguments or use them as return values. Note that many other Clojure functions work with arrays such as via the seq library. The functions listed here exist for initial creation of arrays, or to support mutation or higher performance operations on arrays. Vararg methodsJava vararg methods treat the trailing varargs parameter as an array. They can be invoked from Clojure by passing an explicit array in place of the vargs. Depending on the varargs type, use the type-specific array constructors for primitives or Create array from existing collection: aclone amap to-array to-array-2d into-array Type HintsClojure supports the use of type hints to assist the compiler in avoiding reflection in performance-critical areas of code. Normally, one should avoid the use of type hints until there is a known performance bottleneck. Type hints are metadata tags placed on symbols or expressions that are consumed by the compiler. They can be placed on function parameters, let-bound names, var names (when defined), and expressions:
Once a type hint has been placed on an identifier or expression, the compiler will try to resolve any calls to methods thereupon at compile time. In addition, the compiler will track the use of any return values and infer types for their use and so on, so very few hints are needed to get a fully compile-time resolved series of calls. Note that type hints are not needed for static fields or the return values of static methods as the compiler always has that type information. There is a *warn-on-reflection* flag (defaults to false) which will cause the compiler to warn you when it can’t resolve to a direct call:
For function return values, the type hint can be placed before the parameter vector:
AliasesClojure provides aliases for primitive Java types and arrays which do not have typical representations as Java class names. The types are represented according to the specification of Java Field Descriptors. For example, byte arrays (byte-array []) have a type of "[B".
param-tagsSince Clojure 1.12, developers can supply A new metadata reader syntax Support for Java PrimitivesClojure has support for high-performance manipulation of, and arithmetic involving, Java primitive types in local contexts. All Java primitive types are supported: int, float, long, double, boolean, char, short, and byte.
Rather than write this Java:
you can write this Clojure:
and the resulting code is exactly the same speed (when run with java -server). The best aspect of this is that you need not do anything special in your initial coding. Quite often these optimizations are unneeded. Should a bit of code be a bottleneck, you can speed it up with minor adornment:
Functions have limited support for primitive arguments and return type: type hints for Thus a function defined as
both takes and returns values of primitive type CoercionsFunctional Interface ConversionJava programs emulate functions with Functional Interfaces, which have a single method. Clojure developers can invoke Java methods taking Functional Interfaces by passing functions with matching arity. The Clojure compiler implicitly converts functions to the required Functional Interface by constructing a lambda adapter. You can explicitly coerce a function to a Functional Interface by hinting the binding name in a Since Clojure 1.12, all Some optimization tips
Java Stream SupportClojure collections implement the Java collection interfaces, which provide Stream and Spliterator access. Clojure persistent vectors implement a custom Spliterator that supports parallel streams. Clojure provides functions (since 1.12) to interoperate with streams in an idiomatic manner, all functions behave analogously to their Clojure counterparts:
All of these operations are terminal stream operations (they consume the stream). Simple XML SupportIncluded with the distribution is simple XML support, found in the src/clj/clojure/xml.clj file. All names from this file are in the clojure.xml namespace. (parse source) Parses and loads the source, which can be a File, InputStream or String naming a URI. Returns a tree of the clojure.xml/element struct-map, which has the keys :tag, :attrs, and :content. and accessor fns tag, attrs, and content.
Calling Clojure From JavaThe clojure.java.api package provides a minimal interface to bootstrap Clojure access from other JVM languages. It does this by providing:
IFns provide complete access to Clojure’s APIs. You can also access any other library written in Clojure, after adding either its source or compiled form to the classpath. The public Java API for Clojure consists of the following classes and interfaces: All other Java classes should be treated as implementation details, and applications should avoid relying on them. To lookup and call a Clojure function:
Functions in clojure.core are automatically loaded. Other namespaces can be loaded via require:
IFns can be passed to higher order functions, e.g. the example below passes
Most IFns in Clojure refer to functions. A few, however, refer to non-function data values. To access these, use
Copyright 2008-2022 Rich Hickey | Privacy Policy
Logo & site design by Tom Hickey Published 2026-11-11
Update this page |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |