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?
In Kotlin we are not allowed to extend multiple superclasses. Multiple-inheritance is achieved by giving concrete functions to interfaces. Now the amount of boilerplate required to achieve this is reduced to a single line.
In Kotlin, there are two constructors: Primary constructor - concise way to initialize a class.
To do so you need to declare a secondary constructor using the constructor keyword. If you want to use some property inside the secondary constructor, then declare the property inside the class and use it in the secondary constructor. By doing so, the declared variable will not be accessed inside the init() block.
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.
Use the @JvmOverloads annotation.
class PhotoLibException: RuntimeException { @JvmOverloads constructor(message: String, ex: Exception?) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With