问题
Possible Duplicate:
Compile file containing java and scala code
I'm aware that Scala can easily use Java classes. However, is it possible to include Java source inside a scala file and have it compile with scalac, in any way?
Alternatively, is it possible to include javac-compiled bytecode as a bytearray in the source, and import from it (yuck, yes)?
This is for homework, so, no, I can't have separate files, and it must compile with scalac file.scala
, with no additional arguments. To clarify, this is a hard requisite by my teacher
回答1:
If you want to write a literal byte array in Scala code, it is easy to go from that to a normal Java class, simply by calling Classloader.defineClass. This means that you need to make your own subclass of ClassLoader
that exposes one of the overloads of this method. This is all doable in Scala without much trouble.
If you carefully prepare this, you may even get type safety, by making your class-from-bytearray implement an interface that you have defined in Scala. I don't know the exact details on this, but I remember it was possible for a Java class to subclass/implement something defined in Scala. Failing that, you certainly have reflection at your disposal.
回答2:
I just wrote a simple example
say you have a java class like this
public class HelloWorld {
public static void main(String[] args) {
System.out.println("hello world");
}
}
Then you write some scala code to turn that into a byte array
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()
And then you can use it like this
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)
回答3:
You could use BCEL and specify a Javac-derived instruction list in the Scala, but I can't really imagine how this is practical in any way. The simplest way to do what you want is to use (say) the Maven scala plugin to compile both Java and Scala files together.
来源:https://stackoverflow.com/questions/13554617/include-java-source-in-scala-file