0

I've been a Java developer for many years developing mostly MVC Web applications using Spring. I am learning Kotlin and Android as a self development project, and mostly love it. I normally just figure things out, but I think I am missing something big here (as I like writing code that is easy to maintain and not prone to Exceptions). I understand the inter-operability with Java, I'm just confused on how my Kotlin code compiles and gives me no sort of warning whatsoever that a Java method call throws an Exception.

Here is a very simple example I have from the Android Tutorials on how to write a file that demonstrates this issue (From Camera Intent Tutorial). File.createTempFile() throws IO Exception in Java but Kotlin allows me to just call this method as if nothing throws any exceptions at all. If I remove the @Throws annotation on the method I get no warning that I'm calling a method that has the potential to throw an Exception.

@Throws(IOException::class)
private fun createImageFile(): File {
    // Create an image file name
    val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
    val storageDir: File = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
    return File.createTempFile(
            "JPEG_${timeStamp}_", /* prefix */
            ".jpg", /* suffix */
            storageDir /* directory */
    ).apply {
        // Save a file: path for use with ACTION_VIEW intents
        currentPhotoPath = absolutePath
    }
}

I'm just confused on how I am supposed to keep track of Java methods that throw Exceptions. I know a lot of Exceptions and this example has the Exception in it, but by no means do I know (or could I know) every Exception possible for every method call in Java and/or Java libraries. Am I supposed to go look at the source code of every method I call to make sure I am not missing an Exception? That seems very tedious and quite a bit of overhead on a large scale codebase.

This is called perfectly fine from my code without the @Throws annotation even though it throws IO Exception in Java. How am I supposed to know if a Java method is throwing an Exception I need to take into account while coding (without looking at the source code)?

private fun createImageFile(): File {
    // Create an image file name
    val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
    val storageDir: File = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
    return File.createTempFile(
            "JPEG_${timeStamp}_", /* prefix */
            ".jpg", /* suffix */
            storageDir /* directory */
    ).apply {
        // Save a file: path for use with ACTION_VIEW intents
        currentPhotoPath = absolutePath
    }
}

I have read the documents on Exceptions and on Java inter-operability, I am just wondering if there is an easier way to tell if a Java method throws an Exception then looking at the source code (maybe I missed something)?

https://kotlinlang.org/docs/reference/java-interop.html https://kotlinlang.org/docs/reference/exceptions.html

//Checked Exceptions
//In Kotlin, all exceptions are unchecked, meaning that the compiler does not force you to catch any 
//of 
// them. So, when you call a Java method that declares a checked exception, Kotlin does not force you 
//to 
//do anything:
fun render(list: List<*>, to: Appendable) {
    for (item in list) {
        to.append(item.toString()) // Java would require us to catch IOException here
    }
}
Twenty
  • 5,234
  • 4
  • 32
  • 67

2 Answers2

0

I suggest you check with Intellij. If I use a method throwing an exception in my code, It hints me. It also suggests me to include throws Exception my method definition

Consider there are 3 methods,

A()throws Exception;
B(); //which calls A inside
C();// which calls B inside

This code will compile in Java without complaining. But it's not the best practice, throw Exception is much important like return type in the method definition. Especially in multi-developer projects. It improves usability and documentation.

Am I supposed to go look at the source code of every method I call to make sure I am not missing an Exception?

While using external libs, you don't need to know about the source code but you must refer the documentation to know about its behaviours.

  1. what's the purpose of the method.
  2. Whether it throws Exception or not. If so, Should I handle it or not.
  3. The return type, which you obviously know.

I am working in a repository maintained by 200 developers. And we also practice the above.

And in addition, Java reflection has the library Method.getExceptionTypes() which will list you all the exceptions throwing by a method in runtime.

Note: I am Java developer and don't know much about Kotlin grammars

Naveen
  • 38
  • 8
0

Since Kotlin doesn't support checked exceptions, you're out of luck when using a Java library. You just have to be diligent about looking at the docs of methods you're calling.

If you're writing a Kotlin library, you can box your result in a class that wraps a successful result or an error. Or you can use sealed classes. For example:

sealed class QueryResult
class Success(val result: List<String>): QueryResult()
class IncorrectSyntaxError(val msg: String): QueryResult()
class ConnectionError(val msg: String): QueryResult()

And then your function can return one of the above subclasses. The receiver can then use a when statement to handle the result:

var result: List<String>? = null
val query = doQuery()
when (query ) {
    is Success -> result = query.result
    is IncorrectSyntaxError -> showErrorMessage(query.msg)
    is ConnectionError -> showErrorMessage(query.msg)
}
Tenfour04
  • 83,111
  • 11
  • 94
  • 154