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