From 5f36b4889a91e606ebcd880fec68896052a9f943 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Fri, 13 Dec 2019 01:25:22 +0530 Subject: [PATCH] Add binary incompatibility post Signed-off-by: Harsh Shandilya --- ...kotlin-part-3--caveats-coming-from-java.md | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/content/posts/teachingkotlin-part-3--caveats-coming-from-java.md b/content/posts/teachingkotlin-part-3--caveats-coming-from-java.md index 7baa3cf..d8418b3 100644 --- a/content/posts/teachingkotlin-part-3--caveats-coming-from-java.md +++ b/content/posts/teachingkotlin-part-3--caveats-coming-from-java.md @@ -18,6 +18,40 @@ Java's `java.lang.String#split` [method](https://docs.oracle.com/javase/8/docs/a ## Runtime asserts -Square's [Jesse Wilson](https://github.com/swankjesse) found through an [OkHttp](https://github.com/square/okhttp) bug that Kotlin's `assert` function differs from Java's in a very critical way - the asserted expression is *always* executed. He's written about it on his blog which you can check out for a proper write up: [Kotlin’s Assert Is Not Like Java’s Assert](https://publicobject.com/2019/11/18/kotlins-assert-is-not-like-javas-assert/). +Square's [Jesse Wilson](https://twitter.com/jessewilson) found through an [OkHttp bug](https://github.com/square/okhttp/issues/5586) that Kotlin's `assert` function differs from Java's in a very critical way - the asserted expression is *always* executed. He's written about it on his blog which you can check out for a proper write up: [Kotlin’s Assert Is Not Like Java’s Assert](https://publicobject.com/2019/11/18/kotlins-assert-is-not-like-javas-assert/). -TL;DR Java's `assert` checks the `java.lang.Class#desiredAssertionStatus` method **before** executing the expression, but Kotlin does it **after** which results in unnecessary, potentially significant overhead. +TL; DR Java's `assert` checks the `java.lang.Class#desiredAssertionStatus` method **before** executing the expression, but Kotlin does it **after** which results in unnecessary, potentially significant overhead. + +{{< highlight java >}} +// Good :) +@Override void flush() { + if (Http2Stream.class.desiredAssertionStatus()) { + if (!Thread.holdsLock(Http2Stream.this) == false) { + throw new AssertionError(); + } + } + ... +} +{{< / highlight >}} + +{{< highlight kotlin >}} +// Bad :( +override fun flush() { + if (!Thread.holdsLock(this@Http2Stream) == false) { + if (Http2Stream::class.java.desiredAssertionStatus()) { + throw AssertionError() + } + } + ... +} +{{< / highlight >}} + +## Binary incompatibility challenges + +[Jake Wharton](https://twitter.com/JakeWharton) wrote in his usual in-depth detail about how the Kotlin `data` class modifier makes it a challenge to modify public API without breaking source and binary compatibility. Kotlin's sweet language features that provide things like default values in constructors and destructuring components become the very thing that inhibits binary compatibility. + +Take about 10 minutes out and give Jake's article a read: [Public API challenges in Kotlin](https://jakewharton.com/public-api-challenges-in-kotlin/). + +## Summary + +While migrating from Java to Kotlin is great, there are many subtle differences between the languages that can blindside you and must be taken into account. It's more than likely that these problems may never affect you, but it's probably helpful to know what's up when they do :)