0

Given the following trait:

trait Foo {

  final val wait = "wait"

}

on compilation it emits the following override compiler error:

Value 'wait' cannot override final member

Declaring a variable inside a trait as above seems to clash with the following Java method in the Object class:

    public final void wait() throws InterruptedException {
        this.wait(0L);
    }

Is this a bug or desired behaviour?

  • 1
    Likely desired behaviour, given that java.lang.Object has a number of methods, including wait: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Object.html#wait() . As a side-note, the decision to include so many methods in `Object` that most/all classes are subtypes of and inherit from might have been a mistake (though hindsight is 20/20). Especially `wait`, `notify` and `notifyAll`, since those are concurrency-specific and part of Java's support for monitors, and it gives some drawbacks to have them on all classes that inherits from `Object`. – MelvinWM May 19 '20 at 09:53
  • that's correct you can't change the value of a final val right? what's the problem? – Raman Mishra May 19 '20 at 09:53

2 Answers2

2

wait is a final method defined in Object on JVM. Any other object extends java.lang.Object, so you cannot override/define methods that are final in it.

This is expected, otherwise you would end up with a weird behavior if you tried to use wait and notify in Java code where object came from part of the code written in Scala. Actually, Scala tries to hold all contracts that Java defined to be on a safe side of things.

Mateusz Kubuszok
  • 24,995
  • 4
  • 42
  • 64
2

In this answer you see that a val field actually also creates a getter method with the name of the field - in your case wait(). Since that clashes with the final wait() method on Object, that is indeed expected.

kutschkem
  • 7,826
  • 3
  • 21
  • 56