nashorn/docs/JavaScriptingProgrammersGuide.html
changeset 19046 6f60d5707c89
parent 18615 3f6e6adcbc1a
child 18846 4ef5f2321c67
equal deleted inserted replaced
19045:bc9a25fff6c5 19046:6f60d5707c89
    69 Classes</a></span></li>
    69 Classes</a></span></li>
    70 <li><span><a href="#jsarrays">Creating, Converting and Using Java
    70 <li><span><a href="#jsarrays">Creating, Converting and Using Java
    71 Arrays</a></span></li>
    71 Arrays</a></span></li>
    72 <li><span><a href="#jsimplement">Implementing Java
    72 <li><span><a href="#jsimplement">Implementing Java
    73 Interfaces</a></span></li>
    73 Interfaces</a></span></li>
    74 <li><span><a href="#jsextend">Extending Java classes
    74 <li><span><a href="#jsextendabstract">Extending Abstract Java Classes
       
    75 </a></span></li>
       
    76 <li><span><a href="#jsextendconcrete">Extending Concrete Java Classes
       
    77 </a></span></li>
       
    78 <li><span><a href="#jsimplementmultiple">Implementing Multiple Java Interfaces
       
    79 </a></span></li>
       
    80 <li><span><a href="#classBoundImplementations">Class-Bound Implementations
    75 </a></span></li>
    81 </a></span></li>
    76 <li><span><a href="#jsoverload">Overload Resolution</a></span></li>
    82 <li><span><a href="#jsoverload">Overload Resolution</a></span></li>
       
    83 <li><span><a href="#dataTypeMapping">Mapping of Data Types Between Java
       
    84 and JavaScript</a></span></li>
       
    85 
       
    86 
       
    87 
    77 </ul>
    88 </ul>
    78 </li>
    89 </li>
    79 <li><span><a href="#engineimpl">Implementing Your Own Script
    90 <li><span><a href="#engineimpl">Implementing Your Own Script
    80 Engine</a></span></li>
    91 Engine</a></span></li>
    81 <li><span><a href="#refs">References</a></span></li>
    92 <li><span><a href="#refs">References</a></span></li>
   214 the same as a global variable with the name "file". The script can
   225 the same as a global variable with the name "file". The script can
   215 access the variable - for example, it can call public methods on
   226 access the variable - for example, it can call public methods on
   216 it. Note that the syntax to access Java objects, methods and fields
   227 it. Note that the syntax to access Java objects, methods and fields
   217 is dependent on the scripting language. JavaScript supports the
   228 is dependent on the scripting language. JavaScript supports the
   218 most "natural" Java-like syntax.</p>
   229 most "natural" Java-like syntax.</p>
       
   230 <p>
       
   231 Nashorn script engine pre-defines two global variables named "context"
       
   232 and "engine". The "context" variable is of type javax.script.ScriptContext
       
   233 and refers to the current ScriptContext instance passed to script engine's
       
   234 eval method. The "engine" variable is of type javax.script.ScriptEngine and
       
   235 refers to the current nashorn script engine instance evaluating the script.
       
   236 Both of these variables are non-writable, non-enumerable and non-configurable
       
   237 - which implies script code can not write overwrite the value, for..loop iteration
       
   238 on global object will not iterate these variables and these variables can not be
       
   239 deleted by script.
   219 <pre><code>
   240 <pre><code>
   220 // <a href="source/ScriptVars.java">ScriptVars.java</a>
   241 // <a href="source/ScriptVars.java">ScriptVars.java</a>
   221 
   242 
   222 import javax.script.*;
   243 import javax.script.*;
   223 import java.io.*;
   244 import java.io.*;
   464  var stringArrayType = Java.type("java.lang.String[]")
   485  var stringArrayType = Java.type("java.lang.String[]")
   465  var int2DArrayType = Java.type("int[][]")
   486  var int2DArrayType = Java.type("int[][]")
   466 </code>
   487 </code>
   467 </pre> 
   488 </pre> 
   468 
   489 
   469 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.:
   490 Note that the name of the type is always a string for a fully qualified name. You can use any of these expressions to create new instances, e.g.:
   470 
   491 
   471 <pre><code>
   492 <pre><code>
   472  var anArrayList = new Java.type("java.util.ArrayList")
   493  var anArrayList = new (Java.type("java.util.ArrayList"))
   473 </code></pre> 
   494 </code></pre> 
   474 
   495 
   475 or
   496 or
   476 
   497 
   477 <pre><code>
   498 <pre><code>
   493  var arctype = Java.type("java.awt.geom.Arc2D")
   514  var arctype = Java.type("java.awt.geom.Arc2D")
   494  var ftype = arctype.Float
   515  var ftype = arctype.Float
   495 </code></pre> 
   516 </code></pre> 
   496 <p>
   517 <p>
   497 You can access both static and non-static inner classes. If you want to create an instance of a non-static inner class, remember to pass an instance of its outer class as the first argument to the constructor.
   518 You can access both static and non-static inner classes. If you want to create an instance of a non-static inner class, remember to pass an instance of its outer class as the first argument to the constructor.
       
   519 </p>
       
   520 <p>
       
   521 In addition to creating new instances, the type objects returned from <code>Java.type</code> calls can also be used to access the
       
   522 static fields and methods of the classes:
       
   523 <pre><code>
       
   524  var File = Java.type("java.io.File")
       
   525  File.createTempFile("nashorn", ".tmp")
       
   526 </code></pre> 
       
   527 <p>
       
   528 Methods with names of the form <code>isXxx()</code>, <code>getXxx()</code>, and <code>setXxx()</code> can also be used as properties, for both instances and statics.
       
   529 </p>
       
   530 <p>
       
   531 A type object returned from <code>Java.type</code> is distinct from a <code>java.lang.Class</code> object. You can obtain one from the other using properties <code>class</code> and <code>static</code> on them.
       
   532 <pre><code>
       
   533  var ArrayList = Java.type("java.util.ArrayList")
       
   534  var a = new ArrayList
       
   535 
       
   536  // All of the following print true:
       
   537  print("Type acts as target of instanceof: " + (a instanceof ArrayList))
       
   538  print("Class doesn't act as target of instanceof: " + !(a instanceof a.getClass()))
       
   539  print("Type is not same as instance's getClass(): " + (a.getClass() !== ArrayList))
       
   540  print("Type's `class` property is same as instance getClass(): " + (a.getClass() === ArrayList.class))
       
   541  print("Type is same as instance getClass()'s `static` property: " + (a.getClass().static === ArrayList))
       
   542 </code></pre> 
       
   543 <p>
       
   544 You can think of the type object as similar to the class names as used in Java source code: you use them as the
       
   545 arguments to the <code>new</code> and <code>instanceof</code> operators and as the namespace for the static fields
       
   546 and methods, but they are different than the runtime <code>Class</code> objects returned by <code>getClass()</code> calls.
       
   547 Syntactically and semantically, this separation produces code that is most similar to Java code, where a distinction
       
   548 between compile-time class expressions and runtime class objects also exists. (Also, Java can't have the equivalent of <code>static</code>
       
   549 property on a <code>Class</code> object since compile-time class expressions are never reified as objects).
   498 </p>
   550 </p>
   499 <hr>
   551 <hr>
   500 <a name="jsimport" id="jsimport"></a>
   552 <a name="jsimport" id="jsimport"></a>
   501 <h3>Importing Java Packages, Classes</h3>
   553 <h3>Importing Java Packages, Classes</h3>
   502 <p>The built-in functions <code>importPackage</code> (in compatibility script) and
   554 <p>The built-in functions <code>importPackage</code> (in compatibility script) and
   556 </pre>
   608 </pre>
   557 <hr>
   609 <hr>
   558 <a name="jsarrays" id="jsarrays"></a>
   610 <a name="jsarrays" id="jsarrays"></a>
   559 <h3>Creating, Converting and Using Java Arrays</h3>
   611 <h3>Creating, Converting and Using Java Arrays</h3>
   560 <p>
   612 <p>
   561 Array element access or length access is
   613 Array element access or length access is the same as in Java.</p>
   562 the same as in Java. Also, a script array can be used when a Java
       
   563 method expects a Java array (auto conversion). So in most cases we
       
   564 don't have to create Java arrays explicitly.</p>
       
   565 <pre><code>
   614 <pre><code>
   566 // <a href="source/javaarray.js">javaarray.js</a>
   615 // <a href="source/javaarray.js">javaarray.js</a>
   567 
   616 
   568 // create Java String array of 5 elements
   617 // create Java String array of 5 elements
   569 var StringArray = Java.type("java.lang.String[]");
   618 var StringArray = Java.type("java.lang.String[]");
   575 print(a[0]);
   624 print(a[0]);
   576 </code>
   625 </code>
   577 </pre>
   626 </pre>
   578 <p>
   627 <p>
   579 It is also possible to convert between JavaScript and Java arrays.
   628 It is also possible to convert between JavaScript and Java arrays.
   580 Given a JavaScript array and a Java type, <code>Java.toJavaArray</code> returns a Java array with the same initial contents, and with the specified component type. 
   629 Given a JavaScript array and a Java type, <code>Java.to</code> returns a Java array with the same initial contents, and with the specified array type. 
   581 </p>
   630 </p>
   582 <pre><code>
   631 <pre><code>
   583  var anArray = [1, "13", false]
   632  var anArray = [1, "13", false]
   584  var javaIntArray = Java.toJavaArray(anArray, "int")
   633  var javaIntArray = Java.to(anArray, "int[]")
   585  print(javaIntArray[0]) // prints 1
   634  print(javaIntArray[0]) // prints 1
   586  print(javaIntArray[1]) // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
   635  print(javaIntArray[1]) // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
   587  print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
   636  print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
   588 </code></pre>
   637 </code></pre>
   589 <p>
   638 <p>
   590 Given a Java array or Collection, <code>Java.toJavaScriptArray</code> returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.i
   639 You can use either a string or a type object returned from <code>Java.type()</code> to specify the type of the array. 
       
   640 You can also omit the array type, in which case a <code>Object[]</code> will be created.
       
   641 </p>
       
   642 <p>
       
   643 Given a Java array or Collection, <code>Java.from</code> returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.
   591 </p>
   644 </p>
   592 <pre><code>
   645 <pre><code>
   593 var File = Java.type("java.io.File");
   646 var File = Java.type("java.io.File");
   594 var listCurDir = new File(".").listFiles();
   647 var listCurDir = new File(".").listFiles();
   595 var jsList = Java.toJavaScriptArray(listCurDir);
   648 var jsList = Java.from(listCurDir);
   596 print(jsList);
   649 print(jsList);
   597 </code></pre>
   650 </code></pre>
   598 <hr>
   651 <hr>
   599 <a name="jsimplement" id="jsimplement"></a>
   652 <a name="jsimplement" id="jsimplement"></a>
   600 <h3>Implementing Java Interfaces</h3>
   653 <h3>Implementing Java interfaces</h3>
   601 <p>A Java interface can be implemented in JavaScript by using a
   654 <p>A Java interface can be implemented in JavaScript by using a
   602 Java anonymous class-like syntax:</p>
   655 Java anonymous class-like syntax:</p>
   603 <pre><code>
   656 <pre><code>
   604 // <a href="source/runnable.js">runnable.js</a>
   657 // <a href="source/runnable.js">runnable.js</a>
   605 
   658 
   629 th.start();
   682 th.start();
   630 th.join();
   683 th.join();
   631 </code>
   684 </code>
   632 </pre>
   685 </pre>
   633 <hr>
   686 <hr>
   634 <a name="jsextend" id="jsextend"></a>
   687 <a name="jsextendabstract" id="jsextendabstract"></a>
   635 <h3>Extending Java classes</h3>
   688 <h3>Extending Abstract Java Classes</h3>
   636 <p>
   689 <p>
   637 If a Java class 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.:
   690 If a Java class 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.:
   638 </p>
   691 </p>
   639 
   692 
   640 <pre><code>
   693 <pre><code>
   669  timer.schedule(function() { print("Hello World!") })
   722  timer.schedule(function() { print("Hello World!") })
   670 </code></pre>
   723 </code></pre>
   671 
   724 
   672 Here, <code>Timer.schedule()</code> expects a <code>TimerTask</code> 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.
   725 Here, <code>Timer.schedule()</code> expects a <code>TimerTask</code> 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.
   673 
   726 
       
   727 <hr>
       
   728 <a name="jsextendconcrete" id="jsextendconcrete"></a>
       
   729 <h3>Extending Concrete Java Classes</h3>
   674 <p>
   730 <p>
   675 To extend a concrete Java class, you have to use <code>Java.extend</code> function.
   731 To extend a concrete Java class, you have to use <code>Java.extend</code> function.
   676 <code>Java.extend</code> returns a type object for a subclass of the specified Java class (or implementation of the specified interface) that acts as a script-to-Java adapter for it.  
   732 <code>Java.extend</code> returns a type object for a subclass of the specified Java class (or implementation of the specified interface) that acts as a script-to-Java adapter for it.  
   677 </p>
   733 </p>
   678 <pre><code>
   734 <pre><code>
   693     }
   749     }
   694 };
   750 };
   695 printSizeInvokedArrayList.size();
   751 printSizeInvokedArrayList.size();
   696 printAddInvokedArrayList.add(33, 33);
   752 printAddInvokedArrayList.add(33, 33);
   697 </code></pre>
   753 </code></pre>
       
   754 <p>
       
   755 The reason you must use <code>Java.extend()</code> with concrete classes is that with concrete classes, there can be a 
       
   756 syntactic ambiguity if you just invoke their constructor. Consider this example:
       
   757 </p>
       
   758 <pre><code>
       
   759 var t = new java.lang.Thread({ run: function() { print("Hello!") } })
       
   760 </code></pre>
       
   761 <p>
       
   762 If we allowed subclassing of concrete classes with constructor syntax, Nashorn couldn't tell if you're creating a new 
       
   763 <code>Thread</code> and passing it a <code>Runnable</code> at this point, or you are subclassing <code>Thread</code> and
       
   764 passing it a new implementation for its own <code>run()</code> method.
       
   765 </p>
       
   766 <hr>
       
   767 <a name="jsimplementmultiple" id="jsimplementmultiple"></a>
       
   768 <h3>Implementing Multiple Interfaces</h3>
       
   769 <p>
       
   770 <code>Java.extend</code> can in fact take a list of multiple types. At most one of the types can be a class, and the rest must
       
   771 be interfaces (the class doesn't have to be the first in the list). You will get back an object that extends the class and 
       
   772 implements all the interfaces. (Obviously, if you only specify interfaces and no class, the object will extend <code>java.lang.Object</code>).
       
   773 <hr>
       
   774 <a name="classBoundImplementations" id="classBoundImplementations"></a>
       
   775 <h3>Class-Bound Implementations</h3>
       
   776 <p>
       
   777 The methods shown so far for extending Java classes and implementing interfaces &ndash; passing an implementation JavaScript object 
       
   778 or function to a constructor, or using <code>Java.extend</code> with <code>new</code> &ndash; all produce classes that take an
       
   779 extra JavaScript object parameter in their constructors that specifies the implementation. The implementation is therefore always bound
       
   780 to the actual instance being created with <code>new</code>, and not to the whole class. This has some advantages, for example in the
       
   781 memory footprint of the runtime, as Nashorn can just create a single "universal adapter" for every combination of types being implemented.
       
   782 In reality, the below code shows that different instantiations of, say, <code>Runnable</code> have the same class regardless of them having
       
   783 different JavaScript implementation objects:
       
   784 </p>
       
   785 <pre><code>
       
   786 var Runnable = java.lang.Runnable;
       
   787 var r1 = new Runnable(function() { print("I'm runnable 1!") })
       
   788 var r2 = new Runnable(function() { print("I'm runnable 2!") })
       
   789 r1.run()
       
   790 r2.run()
       
   791 print("We share the same class: " + (r1.class === r2.class))
       
   792 </code></pre>
       
   793 <p>
       
   794 prints:
       
   795 </p>
       
   796 <pre><code>
       
   797 I'm runnable 1!
       
   798 I'm runnable 2!
       
   799 We share the same class: true
       
   800 </code></pre>
       
   801 <p>
       
   802 Sometimes, however, you'll want to extend a Java class or implement an interface with implementation bound to the class, not to
       
   803 its instances. Such a need arises, for example, when you need to pass the class for instantiation to an external API; prime example
       
   804 of this is the JavaFX framework where you need to pass an Application class to the FX API and let it instantiate it.
       
   805 </p>
       
   806 <p>
       
   807 Fortunately, there's a solution for that: <code>Java.extend()</code> &ndash; aside from being able to take any number of type parameters
       
   808 denoting a class to extend and interfaces to implement &ndash; can also take one last argument that has to be a JavaScript object
       
   809 that serves as the implementation for the methods. In this case, <code>Java.extend()</code> will create a class that has the same
       
   810 constructors as the original class had, as they don't need to take an an extra implementation object parameter. The example below
       
   811 shows how you can create class-bound implementations, and shows that in this case, the implementation classes for different invocations
       
   812 are indeed different:
       
   813 </p>
       
   814 <pre><code>
       
   815 var RunnableImpl1 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") })
       
   816 var RunnableImpl2 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 2!") })
       
   817 var r1 = new RunnableImpl1()
       
   818 var r2 = new RunnableImpl2()
       
   819 r1.run()
       
   820 r2.run()
       
   821 print("We share the same class: " + (r1.class === r2.class))
       
   822 </code></pre>
       
   823 <p>
       
   824 prints:
       
   825 </p>
       
   826 <pre><code>
       
   827 I'm runnable 1!
       
   828 I'm runnable 2!
       
   829 We share the same class: false
       
   830 </code></pre>
       
   831 <p>
       
   832 As you can see, the major difference here is that we moved the implementation object into the invocation of <code>Java.extend</code>
       
   833 from the constructor invocations &ndash; indeed the constructor invocations now don't even need to take an extra parameter! Since
       
   834 the implementations are bound to a class, the two classes obviously can't be the same, and we indeed see that the two runnables no
       
   835 longer share the same class &ndash; every invocation of <code>Java.extend()</code> with a class-specific implementation object triggers
       
   836 the creation of a new Java adapter class.
       
   837 </p>
       
   838 <p>
       
   839 Finally, the adapter classes with class-bound implementations can <i>still</i> take an additional constructor parameter to further
       
   840 override the behavior on a per-instance basis. Thus, you can even combine the two approaches: you can provide part of the implementation
       
   841 in a class-based JavaScript implementation object passed to <code>Java.extend</code>, and part in another object passed to the constructor.
       
   842 Whatever functions are provided by the constructor-passed object will override the functions in the class-bound object.
       
   843 </p>
       
   844 <pre><code>
       
   845 var RunnableImpl = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") })
       
   846 var r1 = new RunnableImpl()
       
   847 var r2 = new RunnableImpl(function() { print("I'm runnable 2!") })
       
   848 r1.run()
       
   849 r2.run()
       
   850 print("We share the same class: " + (r1.class === r2.class))
       
   851 </code></pre>
       
   852 <p>
       
   853 prints:
       
   854 </p>
       
   855 <pre><code>
       
   856 I'm runnable 1!
       
   857 I'm runnable 2!
       
   858 We share the same class: true
       
   859 </code></pre>
   698 <hr>
   860 <hr>
   699 <a name="jsoverload" id="jsoverload"></a>
   861 <a name="jsoverload" id="jsoverload"></a>
   700 <h3>Overload Resolution</h3>
   862 <h3>Overload Resolution</h3>
   701 <p>Java methods can be overloaded by argument types. In Java,
   863 <p>Java methods can be overloaded by argument types. In Java,
   702 overload resolution occurs at compile time (performed by javac).
   864 overload resolution occurs at compile time (performed by javac).
   703 When calling Java methods from a script, the script
   865 When calling Java methods from Nashorn, the appropriate method will be
   704 interpreter/compiler needs to select the appropriate method. With
   866 selected based on the argument types at invocation time. You do not need
   705 the JavaScript engine, you do not need to do anything special - the
   867 to do anything special &ndash; the correct Java method overload variant 
   706 correct Java method overload variant is selected based on the
   868 is selected based automatically. You still have the option of explicitly
   707 argument types. But, sometimes you may want (or have) to explicitly
   869 specifying a particular overload variant. Reasons for this include 
   708 select a particular overload variant.</p>
   870 either running into a genuine ambiguity with actual argument types, or 
       
   871 rarely reasons of performance &ndash; if you specify the actual overload
       
   872 then the engine doesn't have to perform resolution during invocation.
       
   873 Individual overloads of a Java methods are exposed as special properties
       
   874 with the name of the method followed with its signature in parentheses. 
       
   875 You can invoke them like this:</p>
   709 <pre><code>
   876 <pre><code>
   710 // <a href="source/overload.js">overload.js</a>
   877 // <a href="source/overload.js">overload.js</a>
   711 
   878 
   712 var out = java.lang.System.out;
   879 var out = java.lang.System.out;
   713 
   880 
   714 // select a particular print function 
   881 // select a particular print function 
   715 out["println(java.lang.Object)"]("hello");
   882 out["println(Object)"]("hello");
   716 </code>
   883 </code>
   717 </pre>
   884 </pre>
       
   885 <p>
       
   886 Note that you normally don't even have to use qualified class names in 
       
   887 the signatures as long as the unqualified name of the type is sufficient
       
   888 for uniquely identifying the signature. In practice this means that only
       
   889 in the extremely unlikely case that two overloads only differ in 
       
   890 parameter types that have identical unqualified names but come from 
       
   891 different packages would you need to use the fully qualified name of the
       
   892 class.
       
   893 </p>
       
   894 <hr>
       
   895 <a name="dataTypeMapping" id="dataTypeMapping"></a>
       
   896 <h3>Mapping of Data Types Between Java and JavaScript</h3>
       
   897 <p>
       
   898 We have previously shown some of the data type mappings between Java and JavaScript.
       
   899 We saw that arrays need to be explicitly converted. We have also shown that JavaScript functions
       
   900 are automatically converted to SAM types when passed as parameters to Java methods. Most other
       
   901 conversions work as you would expect.
       
   902 </p>
       
   903 <p>
       
   904 Every JavaScript object is also a <code>java.util.Map</code> so APIs receiving maps will receive them directly.
       
   905 </p>
       
   906 <p>
       
   907 When numbers are passed to a Java API, they will be converted to the expected target numeric type, either boxed or
       
   908 primitive, but if the target type is less specific, say <code>Number</code> or <code>Object</code>, you can only
       
   909 count on them being a <code>Number</code>, and have to test specifically for whether it's a boxed <code>Double</code>,
       
   910 <code>Integer</code>, <code>Long</code>, etc. &ndash; it can be any of these due to internal optimizations. Also, you 
       
   911 can pass any JavaScript value to a Java API expecting either a boxed or primitive number; the JavaScript specification's
       
   912 <code>ToNumber</code> conversion algorithm will be applied to the value.
       
   913 </p>
       
   914 <p>
       
   915 In a similar vein, if a Java method expects a <code>String</code> or a <code>Boolean</code>, the values will be
       
   916 converted using all conversions allowed by the JavaScript specification's <code>ToString</code> and <code>ToBoolean</code>
       
   917 conversions.
       
   918 </p>
       
   919 <p>
       
   920 Finally, a word of caution about strings. Due to internal performance optimizations of string operations, JavaScript strings are
       
   921 not always necessarily of type <code>java.lang.String</code>, but they will always be of type <code>java.lang.CharSequence</code>.
       
   922 If you pass them to a Java method that expects a <code>java.lang.String</code> parameter, then you will naturally receive a Java
       
   923 String, but if the signature of your method is more generic, i.e. it receives a <code>java.lang.Object</code> parameter, you can 
       
   924 end up with an object of private engine implementation class that implements <code>CharSequence</code> but is not a Java String.
       
   925 </p>
   718 <hr>
   926 <hr>
   719 <a name="engineimpl" id="engineimpl"></a>
   927 <a name="engineimpl" id="engineimpl"></a>
   720 <h2>Implementing Your Own Script Engine</h2>
   928 <h2>Implementing Your Own Script Engine</h2>
   721 <p>We will not cover implementation of JSR-223 compliant script
   929 <p>We will not cover implementation of JSR-223 compliant script
   722 engines in detail. Minimally, you need to implement the
   930 engines in detail. Minimally, you need to implement the