97

I am in the processing of learning Kotlin and ran into a problem I couldn't figure out. I would like to extend the Java class RuntimeException in Kotlin and be able to use any one of three of its constructors, in different circumstances (based on what info I have at the time I want to throw an exception). In java my class would look like this:

public class PhotoLibException extends RuntimeException {

    public PhotoLibException(String message, RuntimeException ex) {
        super(message, ex);
    }

    public PhotoLibException(String message) {
        super(message);
    }

    public PhotoLibException(RuntimeException ex) {
        super(ex);
    }
}

When I try to do this in Kotlin, I used this answer as a guide: Kotlin secondary constructor however, I had a problem trying to figure out how to invoke the appropriate super constructor correctly. For example, using functions seemed to be a good approach, like this:

fun PhotoLibException(message: String): PhotoLibException {
    val ex = null
    return PhotoLibException(message, ex)
}

fun PhotoLibException(ex: Exception): PhotoLibException {
    val message = ""
    return PhotoLibException(message, ex)
}

class PhotoLibException(message: String, ex: Exception?): RuntimeException(message, ex) {
}

However, in this Kotlin example above, I am always invoking the super constructor with two args, and not invoking the constructor most appropriate to the situation. So what I have above works, but doesn't do exactly what it would do in Java where a different constructor is invoked in each situation. I also tried instantiating a new RuntimeException inside each fun above and casting it to PhotoLibException, but I wasn't allowed to do that.

Can anyone suggest how I would do this correctly in Kotlin?

2 Answers 2

186

Update: Since M11 (0.11.*), you can use secondary constructors to solve this problem:

class PhotoLibException : RuntimeException {
    constructor(message: String, ex: Exception?): super(message, ex) {}
    constructor(message: String): super(message) {}
    constructor(ex: Exception): super(ex) {}
}

Currently, there's no way to call different super-constructors in different context from the same class. It will be supported in the upcoming months, though.

Sign up to request clarification or add additional context in comments.

4 Comments

Hi, does this solution hold good even today (as of kotlin 1.2.41)? I know it works but are there even simpler alternatives?
@Andrey Breslav How would I add a property to this? I.e. Say some boolean which is only PhotoLibException field passed in via constructor
Make sure your not initialising the any of the parent constructor on the same line as declaring the child class. Eg "class Child : Parent (- don't do this initialisation here-) "
Note that this only works if the class doesn't have a primary constructor - all constructors have to be "secondary". That's probably what @Niroshan meant.
5

Use the @JvmOverloads annotation.

class PhotoLibException: RuntimeException {
   @JvmOverloads constructor(message: String, ex: Exception?)
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.