在JavaScript中调用Java类和接口的方法_第1页
在JavaScript中调用Java类和接口的方法_第2页
在JavaScript中调用Java类和接口的方法_第3页
在JavaScript中调用Java类和接口的方法_第4页
在JavaScript中调用Java类和接口的方法_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、在JavaScript中调用Java类和接口的方法刖百本文中所有的代码使用JavaScript写,但你也可以用其他兼容JS的脚本语言。这些例子可作为脚本文件也可以在交互式S中一次运行一个语句的方式来运行。在JavaScript访问对象的属性和方法的语法与Jav语言相同。本文包含如下几部分:i访问Jav类为了在JavaScript访问原生类型或者引用Jav类型,可以调用Javatp函数,该函数根据传入的完整类名返回对应对象的类型。下面代码显示如何获取不同的对象类型:varArrayList=Java.type(java.util.ArrayListvarintTpe=Java.type(int)

2、;varStringArrayTypeJava.type(java.lang.Strivarint2ArrayType=Java.type(int在JavaScri中使用Javatp函数返回的类型对象的方法跟在Jav的类似。例如你可以使用如下方法来实例化一个类:vararraitJavatpavatirraitJava类型对象可用来实例化Jav对象。下面的代码显示如何使用默认的构造函数实例化一个新对象以及调用包含参数的构造函数:varArrayList=Java.type(java.util.ArrayList);vardefaultSizeArrayList=newArrayList;var

3、customSizeArrayList=newArrayList(16);你可以使用Javatp方法来获取对象类型,可以使用如下方法来访问静态属性以及方法:variJavatpavaiiicratpiartp如果要访问内部静态类,可以传递美元符号给Javatp方法。下面代码显示如何返回avaat的02部类:varatJavatpavaatrcat如果你已经有一个外部类类型对象,那么你可以像访问属性一样访问其内部类,如下所示:varrcJavatpavaatrcvaratrcat由于是非静态内部类,必须传递的是外部类实例作为参数给构造函数。虽然在JavaScri中使用类型对象跟在Jav中类似,但

4、其与avaa对象还是有些区别的,这个区别就是ta方法的返回值。你可以使用ca和tatid性来获取这个信息。下面代码显示二者的区别:varArrayList=Java.typejava.util.ArrayList);vara=rrayLst;fthowingaretrprint(Typeactsastartofinstanceof(ainstanceofArrayList)print(Clastactastargetofinstanceo(ainstanceofa.getClassprint(TypeisnotthesameasinstancetClass():+(a.getClass()Ar

5、rayLprint(TypecapropertyistheaainstancesgetClass()(a.getClasprint(TypeistsameasthetaticpropertyoftheinstancesgetClass+(a在语法和语义上,JavaScript在编译时类表达式和运行时对象都和Jav语义类似。不过在Jav中对象是没有名为tati这样的属性,因为编译时的类表达式不作为对象。、导入Jav包和类为了根据其简单的名称来访问Jav类,我们可以使用iprtaca和iprt函数来导入Jav的包和类。这些函数存在于兼容性脚本文件(mozilla_compat.js)中。下面例子展

6、加如何使用importPackage()和importClass()函数:/Loadcompatibilityscriptload(nashorn:mozilla_compat.js);/Importthejava.awtpackageimportPackage(java.awt);/Importthejava.awt.FrameclassimportClass(java.awt.Frame);/CreateanewFrameobjectvarframe=newjava.awt.Frame(hello);/CallthesetVisible()methodframe.setVisible(tr

7、ue);/AccessaJavaBeanpropertyprint(frame.title);可以通过Packages全局变量来访问Java包,例如Packages.java.util.Vector或者Packages.javax.swing.JFrame。但标准的JavaSE包有更简单的访问方式如java对应Packages.java,javax对应Packages.javax,以及org对应P。java.lang包默认不需要导入,因为这会和object、Boolean、Math等其他JavaScript内建的对象在命名上冲突。此外,导入任何Java包和类也可能导致JavaScript全局作

8、用域下的变量名冲突。为了避免冲突,我们定义了一个JavaImporter对象,并通过with语句来限制导入的Java包和类的作用域,如下列代码所示:/CreateaJavaImporterobjectwithspecifiedpackagesandclassestoimportvarGui=newJavaImporter(java.awt,javax.swing);/PasstheJavaImporterobjecttothewithstatementandaccesstheclasses/fromtheimportedpackagesbytheirsimplenameswithinthest

9、atementsbodywith(Gui)varawtframe=newFrame(AWTFrame);varjframe=newJFrame(SwingJFrame);3、使用Java数组为了创建Java数组对象,首先需要获取Java数组类型对象并进行初始化。JavaScript访问数组元素的语法以及length属性都跟Java样,如下列代码所示:varStringArray=Java.type(java.lang.String);vara=newStringArray(5);/Setthevalueofthefirstelementa0=Scriptingisgreat!;/Printth

10、elengthofthearrayprint(a.length);/Printthevalueofthefirstelementprint(a0);给定一个JavaScript数组我们还可以用Javato()方法将它转成Java数组。我们需要将JavaScript数组作为参数传给该方法,并指定要返回的数组类型,可以是一个字符串,或者是类型对象。我们也可以忽略类型对象参数来返回Object数组。转换操作是根据ECMAScript转换规则进行的。下面代码展示如何通过不同的Java.to()的参数将JavaScript数组变成Java数组:/创建一个JavaScript数组varanArray=1,

11、13,false;/将数组转换成java的int数组varjavaIntArray=Java.to(anArray,int);print(javaIntArray0);/printsthenumber1print(javaIntArray1);/printsthenumber13print(javaIntArray2);/printsthenumber0/将JavaScript数组转换成Java的String数组varjavaStringArray=Java.to(anArray,Java.type(java.lang.String);print(javaStringArray0);/prin

12、tsthestring1print(javaStringArray1);/printsthestring13print(javaStringArray2);/printsthestringfalse/将JavaScript数组转换成Java的Object数组varjavaObjectArray=Java.to(anArray);print(javaObjectArray0);/printsthenumber1print(javaObjectArray1);/printsthestring13print(javaObjectArray2);/printsthebooleanvaluefalse你

13、可以使用java.from()方法来将一个Java数组转成JavaScript数组。下面代码演示如何将一个包含当前目录下文件列表的数组转成JavaScript数组:/GettheJavaFiletypeobjectvarFile=Java.type(java.io.File);/CreateaJavaarrayofFileobjectsvarlistCurDir=newFile(.).listFiles();/ConverttheJavaarraytoaJavaScriptarrayvarjsList=Java.from(listCurDir);/PrinttheJavaScriptarray

14、print(jsList);注意:大多数情况下,你可以在脚本中使用Java对象而无需转换成JavaScript对象。4、实现Java接口在JavaScript实现Java接口的语法与在Java总定义匿名类的方法类似。我们只需要实例化接口并用JavaScript函数实现其方法即可。下面代码演示如何实现Runnable接口:/CreateanobjectthatimplementstheRunnableinterfacebyimplementing/therun()methodasaJavaScriptfunctionvarr=newjava.lang.Runnable()run:function

15、()print(running.n);/ThervariablecanbepassedtoJavamethodsthatexpectanobjectimplementing/thejava.lang.Runnableinterfacevarth=newjava.lang.Thread(r);th.start();th.join();如果一个方法希望一个对象,这个对象实现了只有一个方法的接口,你可以传递一个脚本函数给这个方法,而不是传递对象例如,在上面的例子中ThreadO构造函数要求一个实现了Runnable接口的对象作为参数。我们可以利用自动转换的优势传递一个脚本函数给Thread()构造器

16、。下面的例子展示如何创建一个Thread对象而无需实现Runnable接口:/DefineaJavaScriptfunctionfunctionfunc()print(Iamfunc!);/PasstheJavaScriptfunctioninsteadofanobjectthatimplements/thejava.lang.Runnableinterfacevarth=newjava.lang.Thread(func);th.start();th.join();你可以通过传递相关类型对象给Java.extend()函数来实现多个接口。5、扩展抽象Java类你可以实例化一个匿名的抽象类的子类

17、,只需要给构造函数传递一个JavaScript对象,对象中包含了一些属性对应了抽象类方法实现的值。如果一个方法是重载的,JavaScript函数将会提供所有方法变种的实现。下面例子显示如何初始化抽象类TimerTask的子类:varTimerTask=Java.type(java.util.TimerTask);vartask=newTimerTask(run:function()print(HelloWorld!);除了调用构造函数并传递参数,我们还可以在new表达式后面直接提供参数。下面的例子显示该语法的使用方法(类似Java匿名内部类的定义),这比上面的例子要简单一些:vartask=n

18、ewTimerTaskrun:function()print(HelloWorld!);如果抽象类包含单个抽象方法(SAM类型),那么我们就无需传递JavaScript对象给构造函数,我们可以传递一个实现了该方法的函数接口。下面的例子显示如何使用SAM类型来简化代码:vartask=newTimerTask(function()print(HelloWorld!);不管你选择哪种语法,如果你需要调用一个包含参数的构造函数,你可以在实现对象和函数中指定参数。如果你想要调用一个要求SAM类型参数的Java方法,你可以传递一个JavaScript函数给该方法。Nashorn将根据方法需要来实例化一个

19、子类并使用这个函数去实现唯一的抽象方法。下面的代码显示如何调用Timer.schedule()方法,该方法要求一个TimerTask对象作为参数:varTimer=Java.type(java.util.Timer);Timer.schedule(function()print(HelloWorld!);注意:前面的语法假设所要求的SAM类型是一个接口或者包含一个默认构造函数,Nashorn用它来初始化一个子类。这里是无法使用不包含默认构造函数的类的。6、扩展具体Java类为了避免混淆,扩展抽象类的语法不能用于扩展具体类。因为一个具体类是可以被实例化的,这样的语法会被解析成试图创建一个新的类实

20、例并传递构造函数所需类的对象(如果预期的对象类型是一个接口)。为了演示这个问题,请看看下面的示例代码:vart=newjava.lang.Thread(run:function()print(Threadrunning!);这行代码被解析为扩展了Thread类并实现了run()方法,而Thread类的实例化是通过传递给其构造函数一个实现了Runnable接口的对象。为了扩展一个具体类,传递其类型对象给Java.extend()函数,然后返回其子类的类型对象。紧接着就可以使用这个子类的类型对象来创建实例并提供额外的方法实现。下面的代码将向你展示如何扩展Thread类并实现run()方法:varT

21、hread=Java.type(java.lang.Thread);varthreadExtender=Java.extend(Thread);vart=newthreadExtender()run:function()print(Threadrunning!);Java.extend()函数可以获取多个类型对象的列表。你可以指定不超过一个Java的类型对象,也可以指定跟Java接口一样多的类型对象数量。返回的类型对象扩展了指定的类(或者是javalangObject,如果没有指定类型对象的话),这个类实现了所有的接口。类的类型对象无需在列表中排在首位。7、访问超类(父类)的方法想要访问父类的

22、方法可以使用Java.super()函数。下面的例子中显示如何扩展java.lang.Exception类,并访问父类的方法。Example3-1访问父类的方法(super.js)varException=Java.type(java.lang.Exception);varExceptionAdapter=Java.extend(Exception);varexception=newExceptionAdapter(MyExceptionMessage)getMessage:function()var_super_=Java.super(exception);return_super_.get

23、Message().toUpperCase();trythrowexception;catch(ex)print(exception);如果你运行上面代码将会打印如下内容:jdk.nashorn.javaadapters.java.lang.Exception:MYEXCEPTIONMESSAGE8、绑定实现到类前面的部分我们描述了如何扩展Java类以及使用一个额外的JavaScript对象参数来实现接口。实现是绑定的具体某个实例上的,这个实例是通过new来创建的,而不是整个类。这样做有一些好处,例如运行时的内存占用,因为Nashorn可以为每个实现的类型组合创建一个单一的通用适配器。下面的例

24、子展示不同的实例可以是同一个Java类,而其JavaScript实现对象却是不同的:varRunnable=java.lang.Runnable;varr1=newRunnable(function()print(Imrunnable1!);varr2=newRunnable(function()print(Imrunnable2!);r1.run();r2.run();print(Wesharethesameclass:+(r1.class=r2.class);上述代码将打印如下结果:Imrunnable1!Imrunnable2!Wesharethesameclass:true如果你想传递

25、类的实例给外部API(如JavaFX框架,传递Application实例给JavaFXAPI),你必须扩展一个Java类或者实现了与该类绑定的接口,而不是它的实例。你可以通过传递一个JavaScript对象绑定实现类并传递给Java.extend()函数的最后一个参数。这个会创建一个跟原有类包含一样构造函数的新类,因为它们不需要额外实现对象参数。下面的例子展示如何绑定实现到类中,并演示在这种情况下对于不同调用的实现类是不同的:varRunnableImpl1=Java.extend(java.lang.Runnable,function()print(Imrunnable1!);varRunn

26、ableImpl2=Java.extend(java.lang.Runnable,function()print(Imrunnable2!);varr1=newRunnableImpl1();varr2=newRunnableImpl2();r1.run();r2.run();print(Wesharethesameclass:+(r1.class=r2.class);上面例子执行结果如下:Imrunnable1!Imrunnable2!Wesharethesameclass:false将实现对象从构造函数调用移到Javaextend()函数调用可以避免在构造函数调用中所需的额外参数。每一个J

27、avaextend()函数的调用都需要一个指定类的实现对象生成一个新的Java适配器类。带类边界实现的适配器类仍可以使用一个额外的构造参数用来进一步重写特定实例的行为。因此你可以合并这两种方法:你可以在一个基础类中提供部分JavaScript实现,然后传递给Java.extend()函数,以及在对象中提供实例实现并传递给构造函数。对象定义的函数并传递给构造函数时将覆盖对象的一些函数定义。下面的代码演示如何通过给构造函数传递一个函数来覆盖类边界对象的函数:varRunnableImpl=Java.extend(java.lang.Runnable,function()print(Imrunnab

28、le1!);varr1=newRunnableImpl();varr2=newRunnableImpl(function()print(Imrunnable2!);r1.run();r2.run();print(Wesharethesameclass:+(r1.class=r2.class);上面例子执行后打印结果如下:Imrunnable1!Imrunnable2!Wesharethesameclass:true9、选择方法重载变体Java的方法可以通过使用不同的参数类型进行重载。Java编译器(javac)会在编译时选择正确的方法来执行。在Nashorn中对Java重载方法的解析实在方法被调用的时候执行的。也是根据参数类型来确定正确的方法。但如果实际的参数类型会导致模棱两可的情况下,我们可以显式的指定具体某个重载变体。这会提升程序执行的性能,因为Nashorn引擎无需在调用过程中去辨别该调用哪个方法。重载的变种作为特别的属性暴露出来。我们可以用字符串的形式来引用它们,字符串包含方法名称、参数类型,两者使用圆括号包围起来。下面的例子显示如何调用System.out.println()方法带Object参数的变种,我们传递一个“

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论