5

For example:

FileOutputStream("file") 

would compile in Kotlin, but in Java it would give a compiler error. Why?

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Nour Eldin Ahmed
  • 273
  • 5
  • 14

2 Answers2

4

Kotlin does away with Java's checked exceptions. Exceptions checked at compile time and declared in method signatures, though familiar to Java developers, are widely considered a failed experiment outside and to some degree inside the Java community.

So Kotlin did away with them, and with some of the boilerplate associated with using resources (like FileOutputStream) with the .use method shorthand for Java 7's try-with-resources.

Nate Vaughan
  • 3,471
  • 4
  • 29
  • 47
  • 1
    So what would be the appropriate way to handle those exceptions if i didn't know that they will occur in advance? – Nour Eldin Ahmed Dec 10 '17 at 08:38
  • 1
    In the case of Java classes used in Kotlin, you can simply check the interface method signature or Javadoc. There may be some exceptions that you want to recover from and others that you want to let kill your thread. As mentioned above, `FileOutputStream(File("path")).use{ ... }` is most likely what you are looking for. – Nate Vaughan Dec 10 '17 at 15:55
  • 1
    @NateVaughan If it's a Kotlin interface, it won't have any exceptions declared. And what if there is no Javadoc or it's incomplete? – Malcolm Mar 16 '18 at 09:40
  • @Malcolm If you really don’t trust the code, or know what exceptions it throws, you will handle any exceptions the same way you handle runtime exceptions: using catch(Exception e) – Nate Vaughan Nov 16 '18 at 17:11
  • 4
    @NateVaughan Then how am I supposed to recover from them if I don't know which ones I can get? This is so-called Pokemon exception handling (catch-em-all). Catch any and very helpfully say to the user that something is wrong, but I don't know what? That's precisely the problem with exceptions in Kotlin. – Malcolm Nov 17 '18 at 22:10
  • 1
    @Malcolm You have exactly the same problem with libraries that throw RuntimeExceptions, have throws Exception in their method signatures, or wrap a specific exception in a generic one (e.g. KryoException). The problem as you describe it exists only with code you do not control that throws thoughtful, detailed exceptions that somehow did not make it into any documentation, which I think you'll find is very rare. – Nate Vaughan Nov 18 '18 at 15:33
  • 4
    @NateVaughan Even discerning an `IOException` from `Exception` helps, there's nothing "thoughtful, detailed" in this. And exceptions can be missing from documentation for the same simple reason that the library authors don't have any compiler help when writing documentation either. Also I don't understand why this is supposed to happen only with the code you don't control. In my own code I often forget which methods can throw which exceptions either, and I'd rather have compiler tell me than writing all this stuff out by hand in comments (which you can also forget to check). – Malcolm Nov 18 '18 at 21:53
  • So... for the sounds of it, we need to use `.use{...}` everywhere, regardless if we need to or not, else we have to spend hours going over Java documentation to know when to use `use`... brilliant. – acarlstein Oct 12 '21 at 15:11
3

It can be difficult to answer without letting some opinions interfere. I will just say that Kotlin is aimed at large software projects and give you what the Kotlin team claims regarding checked exceptions (from https://kotlinlang.org/docs/reference/exceptions.html):

Checked Exceptions

Kotlin does not have checked exceptions. There are many reasons for this, but we will provide a simple example.

The following is an example interface of the JDK implemented by StringBuilder class:

Appendable append(CharSequence csq) throws IOException; What does this signature say? It says that every time I append a string to something (a StringBuilder, some kind of a log, a console, etc.) I have to catch those IOExceptions. Why? Because it might be performing IO (Writer also implements Appendable)… So it results into this kind of code all over the place:

try {
    log.append(message)
}
catch (IOException e) {
    // Must be safe
}

And this is no good, see Effective Java, Item 65: Don't ignore exceptions.

Bruce Eckel says in Does Java need Checked Exceptions?:

Examination of small programs leads to the conclusion that requiring exception specifications could both enhance developer productivity and enhance code quality, but experience with large software projects suggests a different result – decreased productivity and little or no increase in code quality.

Other citations of this sort:

Java's checked exceptions were a mistake (Rod Waldhoff)

The Trouble with Checked Exceptions (Anders Hejlsberg)

Ekeko
  • 1,879
  • 14
  • 15