我有一个简单的Java类,它有一些方法:
public class Utils {
public void deal(String price, int amount) {
// ....
}
public void bid(String price, int amount) {
// ....
}
public void offer(String price, int amount) {
// ....
}
}
我想创建这个类的一个实例,并允许Javascript代码直接调用这些方法,如下所示:
deal("1.3736", 100000);
bid("1.3735", 500000);
我现在唯一可以理解的方法是使用
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
engine.put("utils", new Utils());
然后在Javascript代码中使用utils.deal(...)
。我也可以在Javascript中为每个方法编写包装函数,但应该有一种更简单的方法来自动为类的所有公共方法执行此操作。
答案 0 :(得分:7)
我对Rhino并不熟悉,但这样的事情应该有效:
for(var fn in utils) {
if(typeof utils[fn] === 'function') {
this[fn] = (function() {
var method = utils[fn];
return function() {
return method.apply(utils,arguments);
};
})();
}
}
只需遍历utils
的属性,并为每个函数创建一个调用它的全局函数。
import javax.script.*
class Utils {
void foo(String bar) {
println bar
}
}
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
engine.eval("""
for(var fn in utils) {
if(typeof utils[fn] === 'function') {
this[fn] = (function() {
var method = utils[fn];
return function() {
return method.apply(utils,arguments);
};
})();
}
}
foo('foo'); // prints foo, sure enough
""",new SimpleBindings("utils":new Utils()))
答案 1 :(得分:4)
我不确定如何使用JSR-223 API,但是使用Rhino API,您可以使用您想要添加的方法创建FunctionObject
。
Class[] parameters = new Class[] { String.class, Integer.class };
Method dealMethod = Utils.class.getMethod("deal", parameters);
engine.put("deal", new FunctionObject("deal", dealMethod, scope));
文档位于https://www.mozilla.org/rhino/apidocs/org/mozilla/javascript/FunctionObject.html。
您可能需要引用Rhino库来访问FunctionObject
类,我不确定如何使用JSR-223 API获取scope
对象(尽管如此,它可能是null
可行。)
答案 2 :(得分:0)
如果您使用rhino API而不是ScriptEngine API,则可以使用此答案:https://stackoverflow.com/a/16479685/1089998。
我更喜欢这种方法而不是Noah的答案,因为这意味着你不需要在每次执行之前执行随机的javascript代码。
我在这里有一个有效的例子:
答案 3 :(得分:0)
使用Java Lambdas(因此从1.8开始)实际上可以做到这一点:
import java.util.*;
public class Student
{
Scanner werp = new Scanner(System.in);
private String name;
private LinkedList<Double> hwGrades = new LinkedList<Double>();
private LinkedList<Double> testGrades = new LinkedList<Double>();
private LinkedList<Double> labGrades = new LinkedList<Double>();
private double hwGrade, testGrade, labGrade;
private double hwCount = 0, testCount = 0, labCount = 0;
private double hwSum = 0, labSum = 0, testSum = 0;
private double finalGrade = 0;
private char letterGrade = 'Q';
public void Student(String n)
{
String name = n;
LinkedList<Double> labGrades = new LinkedList<Double>();
LinkedList<Double> hwGrades = new LinkedList<Double>();
LinkedList<Double> testGrades = new LinkedList<Double>();
double hwAvg = 0, testAvg = 0, labAvg = 0;
double hwSum = 0, testSum = 0, labSum = 0;
double hwCount = 0, testCount = 0, labCount = 0;
double finalGrade = 0;
}
public void getGrades(LinkedList<Double> L, double count, double sum, double grade, String Z)
{
System.out.println("Enter the " + Z + " grades for " + name + "\n Mark the end of your answers with a negative number:");
OUTER_LOOP:
while(grade >= 0)
{
grade = werp.nextDouble();
if (grade < 0 && grade != -1 || grade > 105) {System.out.println("Error! Incorrect scoring range" + "\n Enter a number between 0 and 105");}
else if (grade == -1) {break OUTER_LOOP;}
else
{
L.add(grade);
count++;
sum += grade;
}
}
}
}