5

I'm trying to find the simplest yet proper way to extend a Java Exception in Scala. For example, the following is not correct because new Exception(null, cause) and new Exception(cause) have different behavior according to Throwable.java:

class InvalidVersionException(message: String = null, cause: Throwable = null)
  extends IllegalArgumentException(message, cause) {
  def this(message: String) = this(message, null)
  // This is not same with super(cause)
  def this(cause: Throwable) = this(null, cause)
}

Because I know Throwable(cause) sets the message to cause.toString(), I came up with the following:

class InvalidVersionException(message: String = null, cause: Throwable = null)
  extends IllegalArgumentException(if ((message eq null) && (cause ne null)) cause.toString else message, cause) {
  def this(message: String) = this(message, null)
  def this(cause: Throwable) = this(null, cause)
}

However, this still has:

if ((message eq null) && (cause ne null)) cause.toString

which was duplicated from Throwable.java.

Is there a better way to extend an Exception without any code duplication?

4

3 回答 3

2

It looks to me like you should be able to just change the cause-only constructor to:

def this(cause: Throwable) = this(cause.toString, cause)

EDIT: To handle null cause:

def this(cause: Throwable) = this(if (cause == null) "(no message)" else cause.toString, cause)

Replace "(no message)" with null (not recommended) or whatever text you feel is appropriate.

于 2013-08-20T09:06:12.323 回答
0

How about this?

trait InvalidVersionException extends IllegalArgumentException

object InvalidVersionException {
  def apply(msg: String) = new IllegalArgumentException(msg) with InvalidVersionException
  def apply(cause: Throwable) = new IllegalArgumentException(cause) with InvalidVersionException
  def apply(msg: String, cause: Throwable) = new IllegalArgumentException(msg, cause) with InvalidVersionException
}

(via "In Scala, how can I subclass a Java class with multiple constructors?")

于 2013-08-20T13:47:25.763 回答
0

Based on the answer by @Shadowlands, I ended up with the following:

class InvalidVersionException(message: String, cause: Throwable = null)
  extends IllegalArgumentException(message, cause) {
  def this(cause: Throwable) = this(if (cause ne null) cause.toString else null, cause)
  def this() = this(null)
}

.. which saves 54 bytes.

于 2013-08-30T04:49:16.093 回答