class MyException(message: String) extends Exception(message) {
def this(message: String, cause: Throwable) {
this(message)
initCause(cause)
}
def this(cause: Throwable) {
this(Option(cause).map(_.toString).orNull, cause)
}
def this() {
this(null: String)
}
}
C'est presque identique à @Jacek L. de réponse. Je voulais juste ajouter un peu plus d'entrée sur le motif derrière cette réponse.
Pourquoi de nombreux constructeurs?
Throwable
est écrit dans une sorte de drôle de façon. Il dispose de 4 constructeurs
-- en ignorant l'un avec l' boolean
bascule -- chacun d'eux se comporte un peu différemment avec null
s, et ces différences ne peuvent être maintenus avec plusieurs constructeurs.
Il aurait été un peu plus propre si Scala aurait permis d'appeler un constructeur de la superclasse via super
, mais il n'a pas :(
Pourquoi pas une affaire de classe?
- Parfaitement maintenir les constructeurs de comportement concernant l'
null
s ne serait pas possible; en particulier, les deux def this()
et def this(message: String)
devrez définir le cause
de null
, alors qu'au départ, il est mis à l' this
.
-
toString
ne sera pas remplacée.
- Le message et la cause sont déjà accessibles au public via
getMessage
et getCause
. L'ajout d'une autre référence à ces est redondante.
-
equals
sera remplacée et va se comporter différemment.
Signification, new Exception("m") == new Exception("m") // false
alors qu' new CaseException("m") == new CaseException("m") // true
Si l'on désire accéder au message et à la cause via le pattern matching, on peut simplement mettre en œuvre l' unapply
méthode:
object MyException {
def unapply(e: MyException): Option[(String,Throwable)] = Some((e.getMessage, e.getCause))
}