Scala Multiple Constructors
A couple of weeks ago I created a new type of exception for use in our application. If I’d been using Java I would have written something simple like this:
public class MyException extends RuntimeException {
public MyException(String message) {
super(message);
}
public MyException(String message, Throwable throwable) {
super(message, throwable);
}
}
The Scala multiple constructor model is different to the Java one, as described in this article. In Scala, only the primary class constructor can call a superclass constructor, meaning that it’s only possible to invoke only one superclass constructor. The code above makes calls to two constructors on the RuntimeException class. So how can we write a Scala equivalent? Fortunately one of the answers posted to this question explains a pattern for how to do this:
object MyException {
private def create(message: String): RuntimeException = new RuntimeException(message)
private def create(message: String, throwable: Throwable): RuntimeException = new RuntimeException(message, throwable)
}
class MyException private (exception: RuntimeException) {
def this(message: String) = this (MyException.create(message))
def this(message: String, throwable: Throwable) = this (MyException.create(message, throwable))
}
I think the pattern is really neat but certainly a lot more complicated that the Java equivalent. I guess this is one of the cases where using Java classes in Scala can be tricky.
[...] This post was mentioned on Twitter by amarjeet. amarjeet said: Scala Multiple Constructors « Liz Douglass http://icio.us/pYgkuX http://ff.im/wtRBg [...]
Tweets that mention Scala Multiple Constructors « Liz Douglass -- Topsy.com
January 11, 2011 at 8:34 am
You may have forgotten the “extends RuntimeException(exception)” from your definition of MyException – otherwise MyException won’t be an exception. I agree it’s a gnarly problem and one that I’ve managed to dodge myself (exceptions seem less common in Scala).
I thought the best solution from the StackOverflow page you referred to leads to the following:
trait AnotherException extends RuntimeException object AnotherException { def apply(message: String) = new RuntimeException(message) with AnotherException def apply(message: String, cause: Throwable) = new RuntimeException(message, cause) with AnotherException } throw AnotherException("oh") throw AnotherException("oh", e)However, I’m mostly satisfied with something like:
class SimpleException(msg: String) extends RuntimeException(msg) throw new SimpleException("oh") throw new SimpleException("oh").initCause(e)Though this does kind of ignore the fact that using the constructor Throwable(cause) initialises the cause and _also_ sets the detail message. The initCause(e) will not set the message if it is null. A flexible Java exception often provides 4 constructors: Ex(), Ex(msg), Ex(cause) and Ex(msg, cause). I really am surprised that this doesn’t come up more in Scala discussions but I think it mostly points to a wart in the core Java libraries.
Steven Shaw
November 2, 2011 at 11:12 am