在Scala中使用Java很簡單,除了一些Scala覺得不好的部份外,Java有的特性基本上Scala都有對應的語法。以下將作一些簡單的注意事項對照。
Scala中所有一切都是物件,所以在Java基本資料型態的部份對應至Scala之後也是物件,這可以在 資料型態 找到相關說明,在Java中的Integer等包裹類別(Wrapper class)的實例,在Scala中就是對應至scala.Int等scala.AnyVal的實例,舉個例子來說,如果在Java中某個方法傳回值(或 參數)是基本型態或者是包裹類別型態,在Scala中一律都是scala.AnyVal的型態。
在Java若使用陣列,例如某個方法傳回 值或參數接受陣列,則Scala中是使用scala.Array型態,例如若傳回型態是int[],在Scala中就是使用Array[Int]型態來接 受,若傳回值是int[][],則Scala中就是使用Array[Array[Int]]來接受。
在Java中如果定義了靜態成員或方法,在Scala中存取的方式就是 單 例物件 的語法,例如在Java中的java.lang.Math定義靜態常數與靜態方法,在Scala中的使用方式就是:
println(java.lang.Math.PI) // 3.141592653589793
println(java.lang.Math.pow(3, 2)) // 9.0
不過,基本上java.lang.Math仍是個類別,你不可以當java.lang.Math是個單例物件,所以下面這句是不行的:
val math = java.lang.Math // 錯誤, object Math is not a value
在Java中定義的介面(interface),在Scala中是當作沒有任何實作的特徵(Trait)來使用。例如在Java中定義:
public interface Some { // 這是 Java
void doSome();
}
編譯過後,在Scala中可以如下實作:
class SomeImpl extends Some {
def doSome {
// ...
}
}
Scala本身有自己的 列舉(Enumeration) 定義方式,但若你在Java中若定義了列舉(enum)型態,在Scala中可以直接使用,例如:
public enum Game { // 這是Java
UP, DOWN, LEFT, RIGHT
}
在編譯過後,可以於Scala中如下使用:
def doAction(a: Game) {
a match {
case Game.UP => println("上")
case Game.DOWN => println("下")
case Game.LEFT => println("左")
case Game.RIGHT => println("右")
}
}
doAction(Game.UP) // 上
在Java中若使用泛型時限制了可用類型,例如:
public class Some<T extends Thread> { // 這是 Java
....
}
在Scala中則視為 上界 語法,所以在Scala中:
val s1 = new Some[Thread]
val s2 = new Some[String] // 編譯錯誤,String 不是 Thread 的子類
在Java中的型態通配字元,在Scala中對應至 既存型態(Existential type),所以若在Java中定義了以下的類別:
import java.util.*;
public class Some {
public void doSome(List<? extends Runnable> rs) {
for(Runnable r : rs) {
r.run();
}
}
}
在Scala中可以這麼傳入物件給doSome()方法:
val list = new java.util.ArrayList[Runnable]
list.add(new Runnable {
def run {
println("XD....")
}
})
val s = new Some
s.doSome(list)
在Scala中如果要使用Java的Thread,而你要處理同步化問題時,Java中的synchronized關鍵字,在Scala中可以這麼使用:
class Some {
def doSome = {
this.synchronized {
// 同步化區塊
}
}
}
上例是以物件自身作為鎖定來源,如果要以別的物件作為物件鎖定來源,則範例如下:
class Some {
private val lock = new Object
def doSome = {
lock.synchronized {
// 同步化區塊
}
}
}