尝试访问类成员时出错(使用Rhino)

时间:2011-05-03 00:14:04

标签: java javascript rhino

尝试使用Rhino创建一个Java / JS链接,其中包含两个非常简单的对象,一个具有第二个类的实例作为一个成员。

运行以下代码会出现以下错误:

org.mozilla.javascript.EcmaError:TypeError:找不到默认值 对象。

问题似乎是从第二个对象中访问成员“a”。我也试过这样的吸气剂:

public Object jsGet_a() {
 return Context.toObject(a, this);
}

但我得到同样的错误。

new A()。doSmth();工作正常,并输出“我正在做的事情” new B()。a.doSmth();提出错误

任何人都可以帮我解决这个问题吗?

谢谢!


public class Test {

    public static class A extends ScriptableObject implements Scriptable {

            public A() {
            };

            public String getClassName() {
                    return "A";
            }

            public void jsFunction_doSmth() {
                    System.out.println("I'm doing something");
            };

    }

    public static class B extends ScriptableObject implements Scriptable {

            private A a = new A();

            public B() {
            };

            public String getClassName() {
                    return "B";
            }

            public void jsConstructor() {
            }

            public A jsGet_a() {
                    return a;
            }

    }

    public static void main(String[] args) {
            try {
                    Context cx = Context.enter();

                    Scriptable scope = cx.initStandardObjects(null, true);
                    ScriptableObject.defineClass(scope, A.class);
                    ScriptableObject.defineClass(scope, B.class);

                    cx.compileString("" +
                                    "new A().doSmth();" +
                                    "new B().a.doSmth();" +
                                    "", "", 1, null).exec(cx, scope);

            } catch (Exception e) {
                    e.printStackTrace();
            }
    }

} 

3 个答案:

答案 0 :(得分:1)

这似乎有效:

  1. 制作上下文和全局范围的私有静态变量。
  2. 为A类添加了jsConstructor
  3. 在B类的jsConstructor中,在代码中创建了一个javascript对象。
  4. 使用Context.toObject(a,this);在jsGet_a()
  5. 中返回类型为Scriptable
  6. 最后,将cx分配给输入的Context并将范围分配给全局范围。

    public class Test
    {
        private static Context cx;    
        private static ScriptableObject scope;
    
        public static class A extends ScriptableObject implements Scriptable {
    
            public A() {
            }
    
            public void jsConstructor() {
            }
    
            public String getClassName() {
                    return "A";
            }
    
            public void jsFunction_doSmth() {
                    System.out.println("I'm doing something");
            }
    
        }
    
        public static class B extends ScriptableObject implements Scriptable {
    
            private A a = new A();
    
            public B() {
            }
    
            public String getClassName() {
                return "B";
            }
    
            public void jsConstructor() {
            Scriptable scriptable = cx.newObject(scope, "A");
                this.put("a", this, scriptable);
            }
    
            public Scriptable jsGet_a() {
                return Context.toObject(a, this);
            }
    
        }
    
        public static void main(String[] args) {
            try {
                cx = Context.enter();
    
                scope = cx.initStandardObjects(null, true);
                ScriptableObject.defineClass(scope, A.class);
                ScriptableObject.defineClass(scope, B.class);
    
                cx.compileString("" +
                                "new A().doSmth();" +
                                "new B().a.doSmth();" +
                                "", "", 1, null).exec(cx, scope);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

答案 1 :(得分:0)

new B().a.doSmth();

无效,因为a是私有的。

new B().jsGet_a().jsFunction_doSmth();

似乎应该有用。

答案 2 :(得分:0)

根据API文档,您可以使用

方法
//  Get a named property from the object.
get(java.lang.String name, Scriptable start) 
你的java对象中的

。我的猜测是你在上面的反射转换错了。