8

In this StackOverflow question I asked about the behavior of the @throws annotation in Scala. Now that I understand how it works I want to ask about best practices with using it. Here's a repost of my code from that question:

abstract class SFoo {
    def bar(): Unit
}

class SFoobar extends SFoo {
    @throws[Exception]
    override def bar(): Unit = {
        throw new Exception("hi there")
    }
}

The problem here is that if I declare a variable as a SFoo in Java, but instantiate it as a SFoobar, the Java compiler is unable to detect the checked exception and a runtime exception will occur. So my inclination would be to declare @throws in the parent class, SFoo.

But say I have another concrete implementation of SFoo:

class SBarfoo extends SFoo {
    override def bar(): Unit = {
        println("no exception here!")
    }
}

In this case, is it appropriate to declare @throws in the parent class if one of its implementations does not throw an exception? What is the best practice here? (Sorry for the subjective question.)

1 Answer 1

5

You don't have to throw the exception every single time in order for the @throws contract to be fulfilled. In fact, the vast majority of the time, you won't. There's nothing wrong with having an implementation that never throws an exception, if it truly belongs as a subclass. I can think of lots of applications where that would make sense. For example, one implementation might use a disk cache, where another one might use a memory cache.

That being said, Scala purposely omitted checked exceptions for a good reason: they violate the open/closed principle because you can't throw a new exception in a subclass without propagating it around to all the existing classes in the hierarchy, as well as methods calling those methods. Checked exceptions were omitted from C# and other recent languages in large part because of how problematic checked exceptions proved to be in real life Java applications. Scala only has checked exceptions for compatibility with Java code. If you won't be calling Scala code from Java code, you shouldn't use them.

4
  • 1
    A checked exception is more or less the same as an Either type and Either sees a fair amount of use in functional languages. In my opinion the real problem with checked exceptions is that a try block is a statement and not an expression, which instantly rules out using one as an argument or on the right hand of an assignment statement. Saying that checked exceptions violate Open/Closed principle because subclasses have to adhere to the superclass's signature is like saying the return type of inherited methods violates OCP.
    – Doval
    Aug 5, 2014 at 22:38
  • @Doval I think he's saying that adding a new type of exception to a subclass' implementation and then checking it means that you have to propagate that check to the superclass, which was my problem with it. I think you are saying the other way around.
    – 2rs2ts
    Aug 6, 2014 at 2:35
  • 2
    @Doval In Scala, try is an expression. Aug 6, 2014 at 6:03
  • @AlexeyRomanov They're not in Java though, which is where the stigma originated.
    – Doval
    Aug 6, 2014 at 13:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.