Scala sets a new milestone in the evolution of modern programming languages with its unification of programming paradigms and its emancipation from unlucky Java language features. Java itself achieved a similar shift from C/C++ fifteen years ago and moreover became a mainstream language.
Main differences are:
switch/case statement found in most
imperative languages, like Java.
@throws annotations can (but
must not) be specified in place of the mandatory throws clauses.
try-catch-finally results in a value
as with most other Scala control structures.
[1]
Further differences are:
Array library
class (in Java and C++ you write <type>[] and
in Ada array (..) of <type>).
Enumeration
library class (in Java and C++ you use the enum construct, and in Ada you write
type E is (..)).
override modifier
to override inherited methods (as in C#, in Java you use the
@Override annotation).
In Scala try-catch-finally returns a value.
[↑]
object ClientApp {
private val SRV_HOST =
System.getProperty("SRV_HOST", "localhost")
private val SRV_PORT =
try System.getProperty("SRV_PORT", "8080").toInt
catch { case e: NumberFormatException => 8080 }
def main(args: Array[String]) { /* .. */ }
}
The same program written in Java:
public class ClientApp {
private static final String SRV_HOST =
System.getProperty("SRV_HOST", "localhost");
private static /*final*/ int SRV_PORT;
static {
try { SRV_PORT = Integer.parseInt(System.getProperty("SRV_PORT", "8080")); }
catch (NumberFormatException e) { SRV_PORT = 8080; }
}
public static void main(String[] args) { /* .. */ }
}
Examples of Scala literals are [↑]
// File literals.scala
object literals extends App {
val twice = (x: Int) => x * 2
val usage = """Usage: scalac <options> <source files>
|where possible standard options include:
|...""".stripMargin
val levels = ('info, 'warning, 'error)
val link =
<a class="external"
href="http://scala-lang.org">Scala <em>2</em></a>
println(twice(3))
println(usage)
println(levels)
println(link)
}
Output:
6
Usage: scalac <options> <source files>
where possible standard options include:
...
('info,'warning,'error)
<a class="external" href="http://scala-lang.org">Scala</a>
Examples of Scala imports [↑]
// File imports.scala
import /*static*/ java.util.Collections._
import java.util.ArrayList
object imports extends App {
val xs = emptyList[Int]()
val ys = new ArrayList(xs); ys add 1
import java.util.LinkedList
val zs = new LinkedList(ys); zs add 2
val v1 = Vector() ++ List(1, 2)
println(v1+"\t"+v1.getClass.getName)
println {
import java.util.Vector
val v2 = new Vector(zs)
v2+"\t"+v2.getClass.getName
}
}
Output:
Vector(1, 2) scala.collection.immutable.Vector [1, 2] java.util.Vector
In Java the protected modifier
gives access both to subclasses and to members of the same package.
In Scala access is granted to subclasses only.
[↑]
For instance:
// File protected.scala package example class Person { protected def nickname = "Nick" } class Student { private var p = new Person() override def toString = p.nickname }
Output:
error: method nickname in class Person \ cannot be accessed in example.Person Access to protected method nickname not permitted ..
String <: CharSequence implies
String[] <: CharSequence[].
public class TestArrays {
static void f(CharSequence[] a) {
for (CharSequence s : a) System.out.println(s);
}
public static void main(String[] args) {
f(args);
}
}
In Scala, arrays are invariant. The above code must be slightly
adapted in order to compile: one can either widen the type of
args ([1]) before passing it to method
f or define another method g
([2]) as follows:
object arrays {
def f(a: Array[CharSequence]) { a foreach println }
def g[T<: CharSequence](a: Array[T]) { a foreach println } // [2]
def main(args: Array[String]) {
f(Array[CharSequence](args: _*)) // [1]
g(args)
}
}
...
class A { class B { @Override public String toString() { return getClass().getName(); } }; @Override public String toString() { return getClass().getName(); } public B newB() { return new B(); } } public class ex1 { public static void main(String[] args) { A a = new A(); //A.B b = new a.B(); // error: package a does not exist A.B b = a.newB(); System.out.println(a); System.out.println(b); } }
The same program written in Scala:
class A { class B { override def toString = getClass.getName }; override def toString = getClass.getName } object ex1 extends Application { val a = new A val b = new a.B println(a) println(b) }
A A$B