Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
titleJavaImporter
// JavaImporter constructor accepts one or more Java Package objects
var imports = new JavaImporter(java.util, java.io);

// a JavaImporter can be used as a "with" expression object
with(imports) {
    // classes from java.util and java.io packages can 
    // can be accessed by unqualified names

    var map = new HashMap(); // refers to java.util.HashMap
    map.put("js", "javascript");
    map.put("java", "java");
    map.put("cpp", "c++");
    print(map);

    var f = new File("."); // refers to java.io.File
    print(f.getAbsolutePath());
}

Java object

"Java" global property is a script object that defines useful functions for script-to-Java interface.

Java.type function

Given a name of a Java type, returns an object representing that type in Nashorn. The Java class of the objects used to represent Java types in Nashorn is not Class but rather StaticClass. They are the objects that you can use with the new operator to create new instances of the class as well as to access static members of the class. In Nashorn, Class objects are just regular Java objects that aren't treated specially. Instead of them, StaticClass instances - which we sometimes refer to as "Java type objects" are used as constructors with the new operator, and they expose static fields, properties, and methods. While this might seem confusing at first, it actually closely matches the Java language: you use a different expression (e.g. java.io.File) as an argument in "new" and to address statics, and it is distinct from the Class object (e.g. java.io.File.class). Below we cover in details the properties of the type objects.

Code Block
titleJava.type
 var arrayListType = Java.type("java.util.ArrayList")
 var intType = Java.type("int")
 var stringArrayType = Java.type("java.lang.String[]")
 var int2DArrayType = Java.type("int[][]")
 
// Note that the name of the type is always a string for a fully qualified name. You can // use any of these types to create new instances, e.g.:
  
 var anArrayList = new Java.type("java.util.ArrayList")
 
// or

 var ArrayList = Java.type("java.util.ArrayList")
 var anArrayList = new ArrayList
 var anArrayListWithSize = new ArrayList(16)
 
// In the special case of inner classes, you can either use the JVM fully qualified name, // meaning using $ sign in the class name, or you can use the dot:

 var ftype = Java.type("java.awt.geom.Arc2D$Float")
 
// and this works too:
  
  var ftype = Java.type("java.awt.geom.Arc2D.Float")

If the type is abstract, you can instantiate an anonymous subclass of it using an argument list that is applicable to any of its public or protected constructors, but inserting a JavaScript object with functions properties that provide JavaScript implementations of the abstract methods. If method names are overloaded, the JavaScript function will provide implementation for all overloads. E.g.:

Code Block
titlenew on abstract class
var TimerTask =  Java.type("java.util.TimerTask")
var task = new TimerTask({ run: function() { print("Hello World!") } })

Nashorn supports a syntactic extension where a "new" expression followed by an argument is identical to invoking the constructor and passing the argument to it, so you can write the above example also as:

Code Block
titleanonymous class like expression
var task = new TimerTask {
    run: function() {
       print("Hello World!")
    }
}

which is very similar to Java anonymous inner class definition. On the other hand, if the type is an abstract type with a single abstract method (commonly referred to as a "SAM type") or all abstract methods it has share the same overloaded name), then instead of an object, you can just pass a function, so the above example can become even more simplified to:

Code Block
titleSAM
 var task = new TimerTask(function() { print("Hello World!") })

The use of functions can be taken even further; if you are invoking a Java method that takes a SAM type, you can just pass in a function object, and Nashorn will know what you meant:

Code Block
titleSAM function conversion
 var timer = new Java.type("java.util.Timer")
 timer.schedule(function() { print("Hello World!") })

Here, Timer.schedule() expects a TimerTask as its argument, so Nashorn creates an instance of a TimerTask subclass and uses the passed function to implement its only abstract method, run(). In this usage though, you can't use non-default constructors; the type must be either an interface, or must have a protected or public no-arg constructor.

Java.extend function