在scala文件中包含java源代码

时间:2012-11-25 19:29:07

标签: java scala compilation

  

可能重复:
  Compile file containing java and scala code

我知道Scala可以轻松使用Java类。但是,是否可以在scala文件中包含Java源代码并以任何方式使用scalac进行编译?

或者,是否可以在源代码中包含javac编译的字节码作为bytearray,并从中导入(是的,是的)?

这是用于家庭作业,所以,不,我不能拥有单独的文件,必须使用scalac file.scala进行编译,没有其他参数。为了澄清,这是我老师的一项艰苦要求

3 个答案:

答案 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文件。