Scripting in Java Tutorial - Java in Scripting Languages








Using the Packages Global Object

Nashorn defines all Java packages as properties of a global variable named Packages.

For example, the java.lang and javax.swing packages may be referred to as Packages.java.lang and Packages.javax.swing, respectively.

The following code uses the java.util.List and javax.swing.JFrame in Nashorn:

// Create a List
var list1 = new Packages.java.util.ArrayList();

// Create a JFrame
var frame1 = new Packages.javax.swing.JFrame("Test");

Nashorn declares java, javax, org, com, edu, and net as global variables that are aliases for Packages.java Packages.javax Packages.org Packages.com Packages.edu, and Packages.net, respectively.

The following code uses the java and javax aliases for Packages.java and Packages.javax:

// Create a List
var list = new java.util.ArrayList();

// Create a JFrame
var frame = new javax.swing.JFrame("Test");




Using the Java Global Object

Nashorn defines a new global object called Java that contains many useful functions to work with Java packages and classes.

The type() function of the Java object imports a Java type into the script.

The following Nashorn code imports the java.util.ArrayList class and creates its object:

// Import java.util.ArrayList type and call it ArrayList
var ArrayList = Java.type("java.util.ArrayList");

// Create an object of the ArrayList type
var list = new ArrayList();

The following code imports java.util.ArrayList and calls it MyList:

var MyList = Java.type("java.util.ArrayList");
var list2 = new MyList();




Using the importPackage() and importClass() Functions

Rhino JavaScript allowed using the simple names of the Java types in script.

Rhino JavaScript had two built-in functions called importPackage() and importClass() to import all classes from a package and a class from a package, respectively.

Nashorn keeps these functions.

To use these functions in Nashorn, load the compatibility module from mozilla_compat.js file using the load() function.

The following code rewrites the above logic in the previous section these functions:

load("nashorn:mozilla_compat.js");
importClass(java.util.ArrayList);
importPackage(javax.swing);

var list = new ArrayList();
var frame = new JFrame("Test");

To use a class from the java.lang package, import it or use the Packages or Java global object to use its fully qualified name.

You cannot import all classes from the java.lang package.

The following code generates an error because the String class name is already defined in JavaScript:

load("nashorn:mozilla_compat.js");
importClass(java.lang.String);

To use the java.lang.String class, use its fully qualified name.

The following code uses the built-in JavaScript String class and the java.lang.String class:

var javaStr = new java.lang.String("Hello"); // Java String class
var jsStr = new String("Hello");             // JavaScript String class

If a class name in the java.lang package does not conflict with a JavaScript top-level class name, you can use the importClass() function to import the Java class.

For example, you can use the following snippet of code to use the java.lang.System class:

load("nashorn:mozilla_compat.js");
importClass(java.lang.System);

var jsStr = new String("Hello");
System.out.println(jsStr);

JavaImporter Object

In JavaScript, you can use the simple names of classes using a JavaImporter object in a with statement.

JavaImporter is a Nashorn function object that can be used as a function or a constructor.

It accepts a list of Java packages and classes. You can create a JavaImporter object as follows. The following code shows how to import all classes from the java.lang package.

var langPkg = new JavaImporter(Packages.java.lang);

The following code shows how to import all classes from the java.lang and java.util packages and the JFrame class from the javax.swing package.

var pkg2 = JavaImporter(java.lang, java.util, javax.swing.JFrame);

It uses the new operator in the first statement. The second statement does not use the new operator, it used JavaImporter as a function. Both statements do the same thing.

The following code creates a JavaImporter object and uses it in a with statement:

var javaLangAndUtilPkg = JavaImporter(java.lang, java.util);

with (javaLangAndUtilPkg) {
   var list = new ArrayList();
   list.add("one");
   System.out.println("List is " + list);
}

Create Java Objects in Nashorn

Use the new operator with a constructor to create a new Java object in scripts. The following code creates a String object in Nashorn:

var JavaString = Java.type("java.lang.String");
var hi = new JavaString("Hello");

The following code in Nashorn creates a java.util.Date object and accesses the object's method via the property names and the method names.

var LocalDate = Java.type("java.time.LocalDate");
var dt = LocalDate.now();
var year = dt.year;             // Use as a property
var month = dt.month;           // Use as a property
var date = dt.getDayOfMonth();  // Use as a method


print("Date:" + dt);
print("Year:" + year + ", Month:" + month + ", Day:" + date);

The following code shows the difference in creating and accessing the length of a JavaScript String and a Java java.lang.String objects:

var jsStr = new String("Hello JavaScript String");
print("JavaScript String: " + jsStr);
print("JavaScript String Length: " + jsStr.length);

// Java String
var javaStr = new java.lang.String("Hello Java String");
print("Java String: " + javaStr);
print("Java String Length: " + javaStr.length());

Overloaded Java Methods

Java resolves the method call for an overloaded method at compile time.

public class Printer {
        public void print(String str) {
                System.out.println("print(String): " + str);
        }/*w ww .  j a  va  2s.com*/

        public void print(Object obj) {
                System.out.println("print(Object): " + obj);
        }

        public void print(Double num) {
                System.out.println("print(Double): " + num);
        }
}

The interpreters of scripting languages resolve an overloaded method depending on the runtime type of the arguments.

var Printer = Java.type("Printer");
var pt = new Printer();

var list = ["Hello", new Object(), 1.5];

for each(var element in list) {
   pt.print(element);
}

JavaScript can select a specific version of the overloaded method.

var Printer = Java.type("Printer");
var pt = new Printer();
pt["print(java.lang.Object)"](10.5); // Calls print(Object)
pt["print(java.lang.Double)"](10.5); // Calls print(Double)