2

This compiles:

public class SandboxJava { //Java
  public Integer cards;
}

But this does not:

class SandboxScala{
  var cards:Int //Throws saying the class must be abstract to have undefined variables
}

Now I know the fact that vars must be initialized but why does not Scala have this functionality of having undefined variables in the first place?

Core_Dumped
  • 4,577
  • 11
  • 47
  • 71
  • 3
    Most likely the designers believed having field which have not been initialised is a bad idea. – Peter Lawrey Jul 02 '16 at 19:43
  • Check https://stackoverflow.com/questions/1791408/what-is-the-difference-between-a-var-and-val-definition-in-scala – Nicolas Jul 02 '16 at 19:44
  • 1
    Having a field of type Int which is always null and can't be anything other than null would be quite strange. And having that is probably an indication that the code has a bug and that the developer forgot to initialize the val. So having the compiler complain about it is a good idea, IMO. – JB Nizet Jul 02 '16 at 19:48
  • 1
    @JBNizet A Scala `Int` cannot be `null`, it's a value type (maps to the JVM's primitive type `int`) and not a reference type. – Jesper Jul 02 '16 at 20:58
  • @Jesper Ah, sorry. Learnt something. Thanks. – JB Nizet Jul 02 '16 at 21:05
  • 3
    If it would be a `var` instead of a `val` you could initialize it with the default value of its type using an underscore: `var cards: Int = _` (would set `cards` to `0`, which is the default value for `Int`). – Jesper Jul 02 '16 at 21:16
  • The problem is neither Java or Scala, it is your example. `val` is somewhat equal to a `final` variable in Java. So your example should be `public final Integer cards;` and this doesn't compile. – Tom Jul 03 '16 at 21:43

4 Answers4

3

In Java, a field that isn't explicitly initialized is still initialized. References are automatically initialized to null and scalar values to 0. The fact that it doesn't need to be explicit is just a kind of shorthand or syntactic sugar.

Local variables are a bit different. They're not automatically initialized, and they can be declared without initialization, but it's a compiler error to access them before initializing them.

public class Foo {
    public static void main(String[] args) {
        int x;
        if(x == 0) {
            System.out.println("Hello.");
        }
    }
}

Results in

Foo.java:4: error: variable x might not have been initialized
        if(x == 0) {
           ^
Kevin Krumwiede
  • 9,868
  • 4
  • 34
  • 82
3

Because although they look similar, they mean different things (have different "semantics"). The Scala equivalent of your Java code:

public class SandboxJava { // Java
  public Integer cards;
}

is this Scala code:

class SandboxScala {
  var cards:Int = _
}

This has (practically) the same semantics as your Java example. In the code above cards:

  • is public-accessible
  • is mutable (because of var)
  • is initialized to its "default value" (because of = _)

Note that it is precisely because cards is mutable (a var) that you can initialize cards to its "default value". That is: val cards = _ does not work, for obvious reasons (you can not change a val afterwards, so you better initialize it with something meaningful).

As other answers have noted, your Scala version is wrong (for the reason I stated above: you have to initialize a val with something).

If one corrected your Scala version with this:

class SandboxScala {
  val cards:Int = SOME_INITIAL_VALUE
}

you could write something semantically equivalent in Java like this:

class SandboxJava {
  public final int cards = SOME_INITIAL_VALUE
}

Note in this case that the Java compiler would also complain if you failed to provide an initial value for cards.

Sebastian N.
  • 1,962
  • 15
  • 26
1

A val is immutable. It can never be set. What use is an uninitialized field that can never be set?

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • Exactly and OPs Java version is incorrect. It should be `public final Integer cards;` and this also doesn't compile. – Tom Jul 03 '16 at 21:41
0

Scala doesn't have abstract modifier when it comes to def/val/var. So when such a member doesn't have a definition it's considered abstract. That's why compiler complains when you try to declare abstract member in a concrete class.

Victor Moroz
  • 9,167
  • 1
  • 19
  • 23