我知道Scala可以轻松使用Java类。但是,是否可以在scala文件中包含Java源代码并以任何方式使用scalac进行编译?
或者,是否可以在源代码中包含javac编译的字节码作为bytearray,并从中导入(是的,是的)?
这是用于家庭作业,所以,不,我不能拥有单独的文件,必须使用scalac file.scala
进行编译,没有其他参数。为了澄清,这是我老师的一项艰苦要求
答案 0 :(得分:3)
如果你想在Scala代码中编写一个文字字节数组,只需调用Classloader.defineClass
就可以很容易地从那个类到普通的Java类。这意味着您需要创建自己的ClassLoader
子类,以暴露此方法的一个重载。这一切都可以在Scala中完成,没有太多麻烦。
如果你仔细准备这个,你甚至可以通过使你的class-from-bytearray实现你在Scala中定义的接口来获得类型安全。我不知道具体的细节,但我记得Java类有可能继承/实现Scala中定义的东西。如果做不到这一点,你肯定会有反思。
答案 1 :(得分:3)
我刚写了一个简单的例子
说你有像这样的java类
public class HelloWorld {
public static void main(String[] args) {
System.out.println("hello world");
}
}
然后你编写一些scala代码将其转换为字节数组
import java.io.{FileInputStream, FileOutputStream}
import collection.mutable.ArrayBuffer
val in = new FileInputStream("HelloWorld.class")
val out = new FileOutputStream("HelloWorldBytes.scala")
Console.withOut(out) {
var data = in.read()
print("val helloWorldBytes = Array[Byte](")
print(if(data < 128) data else data - 256)
data = in.read()
while(data >= 0) {
print(", ")
print(if(data < 128) data else data - 256)
data = in.read()
}
println(")")
}
in.close()
out.close()
然后你可以像这样使用它
val helloWorldBytes = Array[Byte](...)
object Loader extends ClassLoader {
override
def findClass(name: String): Class[_] =
if(name == "HelloWorld") defineClass(name, helloWorldBytes, 0, helloWorldBytes.size)
else super.findClass(name)
}
val helloWorld = Loader.loadClass("HelloWorld")
helloWorld.getDeclaredMethod("main", classOf[Array[String]]).invoke(null,null)
答案 2 :(得分:1)
你可以使用BCEL并在Scala中指定一个Javac派生的instruction list,但我无法想象它在任何方面是如何实用的。做你想做的最简单的方法是使用(比方说)Maven scala插件来编译Java和Scala文件。