Sök…


Introduktion

Nashorn är en JavaScript-motor utvecklad i Java av Oracle och har släppts med Java 8. Nashorn tillåter inbäddning av Javascript i Java-applikationer via JSR-223 och gör det möjligt att utveckla fristående Javascript-applikationer, och det ger bättre körtid och bättre efterlevnad av ECMA normaliserad Javascript-specifikation.

Syntax

  • ScriptEngineManager // Ger en upptäckts- och installationsmekanism för ScriptEngine-klasser; använder ett SPI (Service Provider Interface)
  • ScriptEngineManager.ScriptEngineManager () // Rekommenderad konstruktör
  • ScriptEngine // Ger gränssnittet till skriptspråket
  • ScriptEngine ScriptEngineManager.getEngineByName (String shortName) // Fabriksmetod för den givna implementeringen
  • Object ScriptEngine.eval (String script) // Kör det angivna skriptet
  • Object ScriptEngine.eval (Reader reader) // Laddar och kör sedan ett skript från den angivna källan
  • ScriptContext ScriptEngine.getContext () // Returnerar leverantören av standardbindningar, läsare och författare
  • void ScriptContext.setWriter (Writer Writer) // Ställer in destinationen att skicka skriptutdata till

Anmärkningar

Nashorn är en JavaScript-motor skriven i Java och ingår i Java 8. Allt du behöver ingår i paketet javax.script .

Observera att ScriptEngineManager tillhandahåller ett generiskt API som låter dig skaffa skriptmotorer för olika skriptspråk (dvs. inte bara Nashorn, inte bara JavaScript).

Ställ in globala variabler

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

// Define a global variable
engine.put("textToPrint", "Data defined in Java.");

// Print the global variable
try {
    engine.eval("print(textToPrint);");
} catch (ScriptException ex) {
    ex.printStackTrace();
}

// Outcome:
// 'Data defined in Java.' printed on standard output

Hej Nashorn

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

// Execute an hardcoded script
try {
    engine.eval("print('Hello Nashorn!');");
} catch (ScriptException ex) {
    // This is the generic Exception subclass for the Scripting API
    ex.printStackTrace();
}

// Outcome:
// 'Hello Nashorn!' printed on standard output

Kör JavaScript-fil

// Required imports
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.io.FileReader;
import java.io.FileNotFoundException;

// Obtain an instance of the JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

// Load and execute a script from the file 'demo.js'
try {
    engine.eval(new FileReader("demo.js"));
} catch (FileNotFoundException ex) {
    ex.printStackTrace();
} catch (ScriptException ex) {
    // This is the generic Exception subclass for the Scripting API
    ex.printStackTrace();
}

// Outcome:
// 'Script from file!' printed on standard output

demo.js :

print('Script from file!');

Avlyssna skriptutdata

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

// Setup a custom writer
StringWriter stringWriter = new StringWriter();
// Modify the engine context so that the custom writer is now the default
// output writer of the engine
engine.getContext().setWriter(stringWriter);

// Execute some script
try {
    engine.eval("print('Redirected text!');");
} catch (ScriptException ex) {
    ex.printStackTrace();
}

// Outcome:
// Nothing printed on standard output, but
// stringWriter.toString() contains 'Redirected text!'

Utvärdera aritmetiska strängar

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");

//String to be evaluated
String str = "3+2*4+5";
//Value after doing Arithmetic operation with operator precedence will be 16

//Printing the value
try {
    System.out.println(engine.eval(str));
} catch (ScriptException ex) {
    ex.printStackTrace();
}

//Outcome:
//Value of the string after arithmetic evaluation is printed on standard output.
//In this case '16.0' will be printed on standard output.

Användning av Java-objekt i JavaScript i Nashorn

Det är möjligt att skicka Java-objekt till Nashorn-motorn som ska bearbetas i Java-kod. Samtidigt finns det några JavaScript (och Nashorn) specifika konstruktioner, och det är inte alltid tydligt hur de fungerar med java-objekt.

Nedan finns en tabell som beskriver beteende hos inbyggda Java-objekt i JavaScript-konstruktioner.

Testade konstruktioner:

  1. Uttryck i if-klausulen. I JS uttryck i om klausul inte behöver vara booleskt till skillnad från Java. Den utvärderas som falsk för så kallade falska värden (noll, odefinierad, 0, tomma strängar osv)
  2. för varje uttalande har Nashorn en speciell typ av slinga - för varje - som kan iterera över olika JS- och Java-objekt.
  3. Få objektstorlek. I JS har objekt en egenskapslängd, som returnerar storleken på en matris eller en sträng.

Resultat:

Typ Om för varje .längd
Java null falsk Inga iterationer Undantag
Java tom sträng falsk Inga iterationer 0
Java-sträng Sann Iterates över strängkaraktärer Strängens längd
Java-heltal / lång värde! = 0 Inga iterationer odefinierad
Java ArrayList Sann Iterererar över element Listans längd
Java HashMap Sann Iterererar över värden null
Java HashSet Sann Iterates över artiklar odefinierad

recommendatons:

  • Det rekommenderas att använda if (some_string) att kontrollera om en sträng inte är noll och inte tom
  • for each kan användas på ett säkert sätt för att iterera över någon samling, och det leder inte till undantag om samlingen inte är iterable, null eller odefinierad
  • Innan ett objekt får längd måste det kontrolleras för null eller odefinierat (detsamma gäller för alla försök att ringa en metod eller få en egenskap av Java-objekt)

Implementera ett gränssnitt från skriptet

import java.io.FileReader;
import java.io.IOException;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class InterfaceImplementationExample {
    public static interface Pet {
        public void eat();
    }

    public static void main(String[] args) throws IOException {
        // Obtain an instance of JavaScript engine
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("nashorn");

        try {
            //evaluate a script
            /* pet.js */
            /*
                var Pet = Java.type("InterfaceImplementationExample.Pet");
                
                new Pet() {
                    eat: function() { print("eat"); }
                }            
            */
            
            Pet pet = (Pet) engine.eval(new FileReader("pet.js"));
            
            pet.eat();
        } catch (ScriptException ex) {
            ex.printStackTrace();
        }

        // Outcome:
        // 'eat' printed on standard output
    }
}

Ställ in och få globala variabler

// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

try {
    // Set value in the global name space of the engine
    engine.put("name","Nashorn");
    // Execute an hardcoded script
    engine.eval("var value='Hello '+name+'!';");
    // Get value
    String value=(String)engine.get("value");
    System.out.println(value);
} catch (ScriptException ex) {
    // This is the generic Exception subclass for the Scripting API
    ex.printStackTrace();
}

// Outcome:
// 'Hello Nashorn!' printed on standard output


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow