Liz Douglass

Scala Multiple Constructors

with 3 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.

About these ads

Written by lizdouglass

December 15, 2010 at 9:24 am

Posted in Uncategorized

Tagged with ,

3 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

  3. Excellent article, and I’m still amazed that there’s not an easier solution available

    well, this is the best I’ve found so far

    class MissingConfigurationException private(ex: RuntimeException) extends RuntimeException(ex) {
      def this(message:String) = this(MissingConfigurationException(message))
      def this(message:String, throwable: Throwable) = this(MissingConfigurationException(message, throwable: Throwable))
    }
    
    object MissingConfigurationException {
      def apply(message:String) = new MissingConfigurationException(message)
      def apply(message:String, throwable: Throwable) = new MissingConfigurationException(message, throwable: Throwable)
    }
    

    this way you may use the “new MissingConfigurationException” or the apply method from the companion object

    Anyway, I’m still surprised that there isn’t a simpler way to achieve it

    If you have a better idea, you can post it at: http://stackoverflow.com/questions/10925268/define-your-own-exceptions-with-overloaded-constructors-in-scala/10925402#10925402

    opensas

    June 7, 2012 at 3:49 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 )

Google+ photo

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

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: