我有一个课程,我无法改变如下:
public class Foo {
public final int ID=0;
public int bar;
public final Object baz=null;
}
我想要一个覆盖Foo
的匿名内部类,例如:
public Foo newFoo(final int mID, final int mbar, final Object mbaz) {
return new Foo(){
public final int ID = mID;
public int bar = mbar;
public final Object baz = mbaz;
};
}
然后我有一个javax.script.ScriptEngine
我希望在JS中调用类似的东西:newFoo(0,0,undefined)["ID"]
我的问题是我得到了这样的例外:
sun.org.mozilla.javascript.internal.WrappedException: Wrapped java.lang.IllegalAccessException: Class sun.org.mozilla.javascript.internal.JavaMembers can not access a member of class Baz$1 with modifiers "public final" (mod.js#9) in test.js at line number 9
我不明白我是如何在这里遇到问题的:如果newFoo
返回普通的'Foo
,但是如果我尝试覆盖Foo
一个匿名的内部类,即使它们是公开的,我也无法访问任何被覆盖的成员。
答案 0 :(得分:2)
我认为这个问题有两个方面。
您的Java代码在语法上是有效的(我认为),但它几乎肯定不会按照您的意愿执行。具体来说,匿名类中的声明不会替换Foo
类中的声明。相反,匿名类的每个实例都有两组字段。 Foo
中声明的方法只能看到原始字段,匿名类中声明的任何方法都会看到新字段。
如果要为匿名子类中的字段设置不同的值,则:
我无法真正建议解决此问题的最佳方法,但我认为您需要启动,方法是将Foo
字段设为私有,并为其提供getter和/或setter他们。对于setter,您可以使用访问修饰符来允许匿名子类设置字段,但不能设置不相关的代码。
最重要的是,您 覆盖字段中的Java。你的代码所做的不是重写,而是隐藏字段。
另一方面是包装异常来自Javascript引擎。我认为问题是匿名类是隐式私有的,因此您的Javascript代码段试图访问私有类的字段。当Javascript引擎尝试这样做时(我希望使用Java反射),它会获得运行时异常。
唯一不幸的是,异常消息并没有说为什么它无法访问该成员,但是你的Java代码足够“奇怪”,这并不让我感到惊讶。
作为解决方法,我建议用非嵌套类替换匿名类。
答案 1 :(得分:-2)
你没有这样的课程:
public class Foo {
public final int ID=0;
public int bar;
public final Object baz;
}
因为那不会编译(baz不能声明)。