Liz Douglass

Scala Multiple Constructors

with 2 comments

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.

Advertisement

Written by lizdouglass

December 15, 2010 at 9:24 am

Posted in Uncategorized

Tagged with ,

2 Responses

Subscribe to comments with RSS.

  1. [...] This post was mentioned on Twitter by amarjeet. amarjeet said: Scala Multiple Constructors « Liz Douglass http://icio.us/pYgkuX http://ff.im/wtRBg [...]

  2. 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


Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.