【发布时间】:2012-03-29 15:22:04
【问题描述】:
更新:
我已经在一定程度上解决了这个问题。以防万一有人遇到同样的问题,这里是最简单的解决方案:查看 MTApplcation 源代码,我发现 initialize() 方法可以重载,采用 String 参数作为要实例化的类的名称。因此,如果我创建一个单独的类来扩展 MTApplication 并在那里传递它的名称,那么一切都会正常工作。
更新结束
我在尝试使用 java 库(MT4j,基于 Processing)时遇到了 Scala 的情况。库想要实例化应用程序的主类(调用者类):
Class<?> c = Thread.currentThread().getContextClassLoader().loadClass(name);
applet = (PApplet) c.newInstance();
以便以后在它的作品中引用它。
但是,它失败了,因为,我猜,主 Scala 类不是一个类,而是一个对象,并且由于库结构,需要调用主库类 MTApplication 的静态方法 initialize()。在 Java 中,静态字段位于类中,但在 Scala 中 - 位于对象中。所以不可能实例化一个对象并且库失败。与 MT4j 相比,Processing 本身在启动时不调用静态方法并成功通过该阶段。
如果我只是创建一个伴生类,一切正常,除了伴生类没有初始化其字段,因为在伴生对象中调用了静态 initialize() 方法,类实例就死了,库变成了无法使用。
至少我是这么理解这个问题的。
我收到此错误:
Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalAccessException: Class processing.core.PApplet can not access a member of class main.Main$ with modifiers "private"
at processing.core.PApplet.runSketch(PApplet.java:9103)
at processing.core.PApplet.main(PApplet.java:9292)
at org.mt4j.MTApplication.initialize(MTApplication.java:311)
at org.mt4j.MTApplication.initialize(MTApplication.java:263)
at org.mt4j.MTApplication.initialize(MTApplication.java:254)
at main.Main$.main(Main.scala:26)
at main.Main.main(Main.scala)
我也很难解释,因为我不完全理解这里发生了什么。但是任何拥有这些库的人都可以在几分钟内重现这种情况,尝试启动主类。
应该实现抽象的startUp() 方法来启动应用程序,让一切看起来更加悲伤。它初始化对象,但库试图使用的是伴随类的一个实例,它没有被初始化,因为在 Scala 中该方法属于该对象。
我的代码:
object Main extends MTApplication {
def main(args: Array[String]) {
MTApplication.initialize()
new Main().startUp()
}
//this method is abstarct so it MUST be implemented,
override def startUp(){
}
}
class Main extends MTApplication {
override def startUp(){
//startup here
}
}
如果我的解释含糊不清,我很抱歉,我只是没有完全理解。可能要理解使用处理源代码而不是预先链接的“core.jar”来重复使用 MT4j 库的实验更容易,以查看内部发生了什么。有人对这里的任何解决方法有想法吗?
【问题讨论】:
标签: scala object static-methods