11.2 在Scala里使用Java类
在Scala里可以直接使用Java类。如果要用的Java类是标准JDK的一部分,直接用就是了。如果它不在java.lang
里,就要导入类的包。下面用到了java.util
和java.lang.reflect
包:
WorkingWithScriptsAndClasses/UseJDKClasses.scala
import java.util.Date
import java.lang.reflect._
println("Today is " + new Date())
val methods = getClass.getMethods()
methods.foreach { method: Method => println(method.getName()) }
如果想用的Java类是你自己创建的,或是来自第三方,请确保scalac的classpath指向字节码的位置。假定我们有如下的Java文件:
WorkingWithScriptsAndClasses/InvestmentType.java
//Java code
package investments;
public enum InvestmentType {
SHORT_TERM,
BOND,
STOCK,
REAL_ESTATE,
COMMODITIES,
COLLECTIBLES,
MUTUAL_FUNDS
}
WorkingWithScriptsAndClasses/Investment.java
//Java code
package investments;
public class Investment {
private String investmentName;
private InvestmentType investmentType;
public Investment(String name, InvestmentType type) {
investmentName = name;
investmentType = type;
}
public int yield() { return 0; }
}
在Scala代码里使用这些类,同使用Scala类是一样的。下面是一个在Scala里创建Investment
实例的例子:
WorkingWithScriptsAndClasses/UseInvestment.scala
import investments._
object UseInvestment {
def main(args: Array[String]) {
val investment = new Investment("XYZ Corporation", InvestmentType.STOCK)
println(investment.getClass())
}
}
假设上面Java文件编译成的字节码位于名为classes/investments的目录下,可以这样编译Scala文件:
scalac -classpath classes UseInvestment.scala
编译完成后这样运行代码:
scala -classpath classes:. UseInvestment
另外,也可以用java运行:
java -classpath \
/opt/scala/scala-2.7.4.final/lib/scala-library.jar:classes:. UseInvestment
输出如下:
class investments.Investment
Investment
类的yield()
方法需要小心使用。如果Java代码有方法或字段的名字(比如trait
或yield
等)与Scala的关键字冲突,调用它们会导致Scala编译器死掉。比如,下面的代码是不行的:
val theYield1 = investment.yield //ERROR
val theYield2 = investment.yield() //ERROR
幸运的是,Scala提供了一个解决方案。把冲突的变量/方法放到反引号里,就可以绕开这个问题。改一下代码就可以让上面的两个调用工作了:
val theYield1 = investment.`yield`
val theYield2 = investment.`yield`()