当像scala脚本一样运行以下内容时,我得到一个InstantiationException。但是当把它放在一个扩展App的类中,然后使用scalac进行编译并使用scala运行时,它可以工作。有什么想法吗?
class A
val foo = classOf[A]
foo.newInstance()
答案 0 :(得分:1)
TL; DR 尝试foo.getConstructors()(0).newInstance(this)
,或使用您自己的multiline shebang
InstantiationException表明你的调用newInstance()正在调用一个不存在的构造函数。
这是一个类似的脚本,打印你的构造函数:
#!/bin/sh
exec scala "$0" "$@"
!#
class A
val foo = classOf[A]
foo.getConstructors.foreach(c => println("Constructor: " + c))
产:
Constructor: public Main$$anon$1$A(Main$$anon$1)
因此,必须将匿名类的实例传递给A的构造函数。
事实证明,Scala脚本由ScriptRunner运行,它使用匿名对象(改编自scala source和Programming Scala)包装脚本:
object Main {
def main(args: Array[String]): Unit = {
new AnyRef {
// Your script code is inserted here.
}
}
}
因此,将外部匿名类this
的实例传递给A的构造函数允许实例化内部类A的新实例。
据我所知,没有办法创建静态内部类within the scala language。基本脚本中的任何构造函数(由scala编译器创建)都需要外部实例。我所知道的其他选项包括字节码操作,以动态地为类创建新的构造函数(方式矫枉过正,imho)或重新实现ScriptRunner。
在shell脚本中的单个exec行期间,Scala实现了ScriptRunner:
#!
您可以使用您想要的任何语言编写自己的外部代码,然后在一行中exec
外部代码。或者您可以使用多行shebang语法在脚本本身中嵌入功能,例如从this page上的Go示例改编的示例:
调试版本,通过sh -x
打印命令,而不是实际删除任何内容:
#!/bin/sh -x
scriptfile=`basename $0`
classname="${scriptfile%.*}"
scalafile="${classname}.scala"
sed -e '1,12d' -e "s/%scala_class_name%/${classname}/" < "$0" > $scalafile
scalac $scalafile
echo todo: rm $scalafile
scala $classname "$@"
STATUS=$?
echo todo: rm "${classname}*.class"
exit $STATUS
######## Scala code starts on line 13
object %scala_class_name% {
def main(args: Array[String]) {
class A
val foo = classOf[A]
println(foo.newInstance())
}
}
我包含调试版本的原因是您可能只想将此作为起点。例如,根据脚本中的其他内容,可能需要进行更多设置或清理,包括:
那里说的是“它应该起作用,但我不保证”以上的版本,它会自行清理:
#!/bin/sh
scriptfile=`basename $0`
classname="${scriptfile%.*}"
scalafile="${classname}.scala"
sed -e '1,12d' -e "s/%scala_class_name%/${classname}/" < "$0" > $scalafile
scalac $scalafile
rm $scalafile
scala $classname "$@"
STATUS=$?
rm "${classname}*.class"
exit $STATUS
######## Scala code starts on line 13
object %scala_class_name% {
def main(args: Array[String]) {
class A
val foo = classOf[A]
println(foo.newInstance())
}
}
原始回答者不适用于Oreilly,但却是一个狂热的消费者。 ;)