动态加载Scala对象
我有许多操作数据库的对象(不是类),我想创建一个较小的助手类,这样我就可以执行类似动态加载Scala对象,scala,dynamic,classloader,dynamic-class-loaders,companion-object,Scala,Dynamic,Classloader,Dynamic Class Loaders,Companion Object,我有许多操作数据库的对象(不是类),我想创建一个较小的助手类,这样我就可以执行类似javamy.helper.class my.database.class的操作,并执行run方法 例如,它编译 trait A extends Runnable class B extends A { def run() = println("run") } object Test extends App { Class.forName(args(0)).newInstance().asInstanceOf[
javamy.helper.class my.database.class
的操作,并执行run
方法
例如,它编译
trait A extends Runnable
class B extends A { def run() = println("run") }
object Test extends App {
Class.forName(args(0)).newInstance().asInstanceOf[A].run()
}
然后做我所期望的
$scala Test B
run
这也编译了
trait A extends Runnable
object B extends A { def run() = println("run") }
object Test extends App {
Class.forName(args(0)).newInstance().asInstanceOf[A].run()
}
但这种情况会发生:
$scala Test B
java.lang.InstantiationException: B
at java.lang.Class.newInstance(Class.java:418)
at Test$.delayedEndpoint$Test$1(Test.scala:9)
at Test$delayedInit$body.apply(Test.scala:8)
at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:383)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
at scala.App$class.main(App.scala:76)
at Test$.main(Test.scala:8)
at Test.main(Test.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at scala.reflect.internal.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:68)
at scala.reflect.internal.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:99)
at scala.reflect.internal.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:68)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:99)
at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:22)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:29)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:72)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:94)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
Caused by: java.lang.NoSuchMethodException: B.<init>()
at java.lang.Class.getConstructor0(Class.java:2971)
at java.lang.Class.newInstance(Class.java:403)
... 28 more
但它也失败了。我知道我可以将所有这些静态对象编入类中,但这在这个应用程序中没有意义,因此我特别寻找一种优雅的方法来实现这一点。我个人认为最优雅的方法是不要动态加载这样的东西。指定有效的输入是否真的那么困难?这使得
A
实例的来源具有更大的灵活性
object Test extends App {
args(0) match {
case "B" => B
case "C" =>
val someOtherConfig = args(1)
new C(someOtherParam)
case other => throw new Exception("invalid input")
} run
}
我将使用解析参数
B$
的构造函数是私有的,这就是代码失败的原因。它是私有的,因此只创建一个实例。这一个实例可以通过静态模块$
@wingedsubmariner访问-给定对象Foo{}
,我如何使用模块$
从字符串“com.Foo$”
获取实际的单例实例?@KevinMeredith从字符串获取?这需要反思。我想提出一个新的问题。是的,我知道这会奏效,但我希望有一个更好的方法来做这件事,而不是长时间的,可能是非穷尽的模式匹配。
object Test extends App {
args(0) match {
case "B" => B
case "C" =>
val someOtherConfig = args(1)
new C(someOtherParam)
case other => throw new Exception("invalid input")
} run
}