The Java solution is actually a workaround to the problem that not all expressions return values, so you can't write this in Java:
final String whatever = if (someCondition) {
"final value"
} else {
"other value"
}
Increasingly, the trend in Java is to use the ternary operator instead:
final String whatever = someCondition ? "final value" : "other value"
Which is fine for that limited use case, but totally untenable once you start dealing with switch statements and multiple constructors.
Scala's approach is different here. All object construction must ultimately pass through a single "primary" constructor, all expressions return a value (even if it's Unit
, equivalent to Java's Void
), and constructor injection is strongly favoured. This results in object graphs being cleanly built as a Directed Acyclic Graph, and also works very nicely with immutable objects.
You also want to be aware that declaring and defining variables in separate operations is, in general, a bad practice when dealing with multiple threads - and could leave you vulnerable to exposing nulls and race conditions when you least expect them (though this isn't really a problem during object construction). The atomic creation of immutable values is just one aspect of the way in which functional languages help to to deal with concurrency.
It also means that the Scala compiler can avoid some of the hideously complicated flow analysis from the Java language spec.
As previously stated, the Scala Way™ is:
val whatever =
if (someCondition)
"final value"
else
"other value"
An approach which also scales up to other control structures:
val whatever = someCondition match {
case 1 => "one"
case 2 => "two"
case 3 => "three"
case _ => "other"
}
With a bit of Scala experience you'll discover that this style helps the compiler to help you, and you should find yourself writing programs with fewer bugs!