在尝试将运行Rhino引擎的旧代码移植到Java 8中的Nashorn时,我遇到了麻烦,无法通过运行js脚本访问静态属性/方法。如果我使用Rhino,它运行得很好。我不知道新Nashorn引擎的实现会发生什么。
import java.util.Scanner;
class case2 {
public static void main(String args[]) {
Scanner entry = new Scanner(System.in);
int a, b;
int i;
do {
System.out.println("Main Menu :");
System.out.println("1. Plus");
System.out.println("2. Minus");
System.out.println("3. Multiply");
System.out.println("4. Division");
System.out.println("5. Exit");
System.out.println("Option :");
i = entry.nextInt();
System.out.println(" ");
switch(i) {
case 1 :
System.out.println("Menu 1 :");
System.out.print("Var A :");
a = entry.nextInt();
System.out.print("Var B :");
b = entry.nextInt();
System.out.println("Result :" + (a+b));
if(a>b) {
System.out.println(a +" > "+b);
}
else if(a<b) {
System.out.println(a +" < "+b);
}
else {
System.out.println(a +" = "+b);
}
System.out.println("*press any key back to menu*");
break;
case 2 :
System.out.println("Menu 2 :");
System.out.print("Var A :");
a = entry.nextInt();
System.out.print("Var B :");
b = entry.nextInt();
System.out.println("Result :" + (a-b));
if(a>b) {
System.out.println(a +" > "+b);
}
else if(a<b) {
System.out.println(a +" < "+b);
}
else {
System.out.println(a +" = "+b);
}
System.out.println("*press any key back to menu*");
break;
case 3 :
System.out.println("Menu 3 :");
System.out.print("Var A :");
a = entry.nextInt();
System.out.print("Var B :");
b = entry.nextInt();
System.out.println("Result :" + (a*b));
if(a>b) {
System.out.println(a +" > "+b);
}
else if(a<b) {
System.out.println(a +" < "+b);
}
else {
System.out.println(a +" = "+b);
}
System.out.println("*press any key back to menu*");
break;
case 4 :
System.out.println("Menu 4 :");
System.out.print("Var A :");
a = entry.nextInt();
System.out.print("Var B :");
b = entry.nextInt();
System.out.println("Result :" + (a/b));
if(a>b) {
System.out.println(a +" > "+b);
}
else if(a<b) {
System.out.println(a +" < "+b);
}
else {
System.out.println(a +" = "+b);
}
System.out.println("*press any key back to menu*");
break;
case 5:
break;
default:
System.out.println("ERROR");
System.out.println("*press any key back to menu*");
}
}while(i != 5);
}
}
答案 0 :(得分:2)
在Nashorn中,您无法通过类实例访问类静态成员。有多种方法可以获得静力学。您可以获得一个充当构造函数和静态命名空间的类型对象,就像Java中的类型名称一样:
var StaticVars = Java.type("StaticVars"); // use your full package name if you have it
print(StaticVars.myname);
或者,传入java.lang.Class
对象并使用.static
伪属性访问静态:
engine.put("StaticVarsClass", StaticVars.class);
接下来是:
var StaticVars = StaticVarsClass.static;
print(StaticVars.myname);
脚本中的。通常,.static
是.class
的反向操作:
var BitSet = Java.type("java.util.BitSet");
var bitSetClass = BitSet.class; // produces a java.lang.Class object, just like in Java
print(BitSet === bitSetClass.static); // prints true
var bitSet = new BitSet(); // type object creates a new bitset when used as a constructor
var thisWontWork = new bitSetClass(); // java.lang.Class can't be used as a constructor.
如您所见,我们区分了三个概念:
java.lang.Class
的实例。它们并不特殊,您只能使用Class
API(.getSuperclass()
,.getName()
等。)这实际上产生了最少的歧义,因为一切都在它的位置,并且最接近Java平台习语。
答案 1 :(得分:0)
这不是js的工作方式。我认为这是Nashorn中的设计错误。假设您有一个混合的util从一些Java运行时系统传递vars到js脚本。该对象包含一个静态方法fmtNumber(someString)和一个对象方法jutil.getFormVar(someString)。用户不需要知道Java正在为此平台提供服务。你只是告诉他们jutil是一个属于框架foo的“系统钩子”。作为这个框架的用户,我不关心它是否静态。我是一名js开发人员,我不知道静态与否。我想快速编写一些东西。这就是rhino中的代码的样子。
var x = jutil.getFormVar("x");
print(jutil.fmtNumber(x));
现在在nashorn,我必须区分它们。更糟糕的是,我甚至必须教育我的用户区分它们并教他们可能不知道的java术语,因为这是抽象层的全部内容:一个自包含系统,而不需要知道底层机制。这种区别是很多认知过载的方式,你没有考虑其他用例,而不是java开发人员为他们自己编写脚本,他们可能不会这样,因为已经知道一种叫做Java的好语言。您正在考虑将您的实现形成为Java开发人员,而您应该考虑如何在后台使用Java Plattform的强大功能,隐藏JS开发人员的所有讨厌细节。如果Web开发人员需要区分浏览器中的静态C ++实现,他会说什么?