{"id":1175,"date":"2026-04-07T10:00:00","date_gmt":"2026-04-07T09:00:00","guid":{"rendered":"https:\/\/wade.one\/blog\/?p=1175"},"modified":"2026-04-07T10:00:00","modified_gmt":"2026-04-07T09:00:00","slug":"what-good-kotlin-code-feels-like-after-too-much-java","status":"publish","type":"post","link":"https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/","title":{"rendered":"What Good Kotlin Code Feels Like After Too Much Java"},"content":{"rendered":"<p>Good Kotlin code usually feels calmer than Java code.<\/p>\n<p>That is the part I keep coming back to. Not faster, not cleverer, not more fashionable. Just calmer. The code asks for less ceremony, says more with less noise, and makes the next change feel less annoying than it should.<\/p>\n<p>I think that is why Kotlin works well for people who have spent enough time in Java to notice the small things. You stop appreciating syntax for its own sake and start caring about whether the code is readable, direct, and hard to misuse.<\/p>\n<h2>The first thing you notice is the lack of ceremony<\/h2>\n<p>Java often makes you pay a tax for simple ideas.<\/p>\n<p>Kotlin still has structure, but it gets out of the way more often. Data classes, named arguments, smart casts, and concise lambdas all help the code read closer to the actual intent. That matters more than people think. When the shape of the code matches the shape of the problem, you spend less time translating in your head.<\/p>\n<p>For me, that is the real benefit. Not that Kotlin is shorter. Shorter code can still be ugly. The useful part is that it usually says the thing more directly.<\/p>\n<h2>Nullability is one of the few features that actually changes behavior<\/h2>\n<p>I trust Kotlin more than Java in part because it makes null handling harder to ignore.<\/p>\n<p>Java lets you wave your hands and hope the null problem stays someone else\u2019s problem. Kotlin forces the question earlier. That does not make bugs impossible, but it does make the risky parts more visible. And once you have worked in enough codebases, visibility is worth a lot.<\/p>\n<p>The best Kotlin code does not abuse <code>!!<\/code> to get around the type system. It uses the type system to describe reality more honestly. If something can be absent, say so. If it cannot, keep it that way. That sounds basic, but basic is usually where the useful discipline starts.<\/p>\n<h2>Extension functions are useful when they remove clutter<\/h2>\n<p>I like extension functions when they make code read naturally.<\/p>\n<p>Used well, they let you attach behavior where it belongs without wrapping everything in a utility class or a pile of static helpers. That can make APIs feel cleaner and more local. You can usually see the intent faster.<\/p>\n<p>But they are also easy to overuse. If every problem turns into an extension function, you end up with code that looks elegant but is harder to trace. The line I try to keep in mind is simple: if the extension makes the code easier to understand, keep it. If it mainly makes the code feel clever, stop.<\/p>\n<h2>Coroutines are good when the code still reads like code<\/h2>\n<p>Coroutines are one of the parts of Kotlin I actually like, because they usually reduce the amount of ceremony around async work without turning everything into callback soup.<\/p>\n<p>That said, they are not magic. They are only good when the surrounding code stays understandable. If you hide too much work in flow operators, nested scopes, or layers of abstraction, you can still make the program hard to reason about. Kotlin gives you nicer tools. It does not save you from bad structure.<\/p>\n<p>What I want from coroutine code is boring clarity. I want to know what runs, where errors go, and what happens when something times out or gets cancelled. If I have to untangle that every time I read the function, the code is not good, no matter how modern it looks.<\/p>\n<h2>Readability still wins<\/h2>\n<p>This is the part people miss when they argue about language style.<\/p>\n<p>Good Kotlin code is not the code with the most language features in it. It is the code that is easiest to read three months later. That usually means keeping the control flow obvious, naming things plainly, and not using language features just because they are there.<\/p>\n<p>If a Kotlin file starts to feel too clever, I usually assume somebody has gone past the useful part.<\/p>\n<p>The best Kotlin code I have seen has a very specific quality: it feels like fewer decisions were left for the reader. The types say more. The null handling is clearer. The async code is easier to follow. The names do more work. The whole thing feels like it wants to be maintained.<\/p>\n<p>That is what good code should feel like.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Kotlin feels good when it removes friction instead of adding ceremony. After enough Java, that difference becomes obvious very quickly.<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[13,25],"tags":[77,79,76,75,78],"class_list":["post-1175","post","type-post","status-publish","format-standard","hentry","category-programming","category-software-engineer","tag-coroutines","tag-extension-functions","tag-java","tag-kotlin","tag-nullability"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>What Good Kotlin Code Feels Like After Too Much Java - wade.one<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"What Good Kotlin Code Feels Like After Too Much Java - wade.one\" \/>\n<meta property=\"og:description\" content=\"Kotlin feels good when it removes friction instead of adding ceremony. After enough Java, that difference becomes obvious very quickly.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/\" \/>\n<meta property=\"og:site_name\" content=\"wade.one\" \/>\n<meta property=\"article:published_time\" content=\"2026-04-07T09:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/Wade-Logo-cropped.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1518\" \/>\n\t<meta property=\"og:image:height\" content=\"1506\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@wadewomersley\" \/>\n<meta name=\"twitter:site\" content=\"@wadewomersley\" \/>\n<meta name=\"twitter:label1\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/04\\\/07\\\/what-good-kotlin-code-feels-like-after-too-much-java\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/04\\\/07\\\/what-good-kotlin-code-feels-like-after-too-much-java\\\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"What Good Kotlin Code Feels Like After Too Much Java\",\"datePublished\":\"2026-04-07T09:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/04\\\/07\\\/what-good-kotlin-code-feels-like-after-too-much-java\\\/\"},\"wordCount\":736,\"publisher\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\"},\"keywords\":[\"coroutines\",\"extension-functions\",\"java\",\"kotlin\",\"nullability\"],\"articleSection\":[\"Programming\",\"Software Engineer\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/04\\\/07\\\/what-good-kotlin-code-feels-like-after-too-much-java\\\/\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/04\\\/07\\\/what-good-kotlin-code-feels-like-after-too-much-java\\\/\",\"name\":\"What Good Kotlin Code Feels Like After Too Much Java - wade.one\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#website\"},\"datePublished\":\"2026-04-07T09:00:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/04\\\/07\\\/what-good-kotlin-code-feels-like-after-too-much-java\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/04\\\/07\\\/what-good-kotlin-code-feels-like-after-too-much-java\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/04\\\/07\\\/what-good-kotlin-code-feels-like-after-too-much-java\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/wade.one\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"What Good Kotlin Code Feels Like After Too Much Java\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/\",\"name\":\"wade.one\",\"description\":\"wade womersley - york based software engineer\",\"publisher\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wade.one\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\",\"name\":\"Wade Womersley\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"contentUrl\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"width\":202,\"height\":200,\"caption\":\"Wade Womersley\"},\"logo\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"What Good Kotlin Code Feels Like After Too Much Java - wade.one","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/","og_locale":"en_GB","og_type":"article","og_title":"What Good Kotlin Code Feels Like After Too Much Java - wade.one","og_description":"Kotlin feels good when it removes friction instead of adding ceremony. After enough Java, that difference becomes obvious very quickly.","og_url":"https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/","og_site_name":"wade.one","article_published_time":"2026-04-07T09:00:00+00:00","og_image":[{"width":1518,"height":1506,"url":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/Wade-Logo-cropped.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_creator":"@wadewomersley","twitter_site":"@wadewomersley","twitter_misc":{"Estimated reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/#article","isPartOf":{"@id":"https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/"},"author":{"name":"","@id":""},"headline":"What Good Kotlin Code Feels Like After Too Much Java","datePublished":"2026-04-07T09:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/"},"wordCount":736,"publisher":{"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3"},"keywords":["coroutines","extension-functions","java","kotlin","nullability"],"articleSection":["Programming","Software Engineer"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/","url":"https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/","name":"What Good Kotlin Code Feels Like After Too Much Java - wade.one","isPartOf":{"@id":"https:\/\/wade.one\/blog\/#website"},"datePublished":"2026-04-07T09:00:00+00:00","breadcrumb":{"@id":"https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/wade.one\/blog\/"},{"@type":"ListItem","position":2,"name":"What Good Kotlin Code Feels Like After Too Much Java"}]},{"@type":"WebSite","@id":"https:\/\/wade.one\/blog\/#website","url":"https:\/\/wade.one\/blog\/","name":"wade.one","description":"wade womersley - york based software engineer","publisher":{"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wade.one\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":["Person","Organization"],"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3","name":"Wade Womersley","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","url":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","contentUrl":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","width":202,"height":200,"caption":"Wade Womersley"},"logo":{"@id":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png"}}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":521,"url":"https:\/\/wade.one\/blog\/2011\/03\/04\/using-ssl-in-restclient\/","url_meta":{"origin":1175,"position":0},"title":"Using SSL in RestClient","author":"Wade","date":"March 4, 2011","format":false,"excerpt":"UPDATE 14\/07\/2012: The author of the client has released version 2.5 a short while ago and also a video for using self-signed certificates in the client. RESTClient is a great little CLI and GUI tool for testing your REST API. I recently pushed a new API up in the office\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/wade.one\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":127,"url":"https:\/\/wade.one\/blog\/2009\/09\/18\/drug-dealers-vs-software-developers\/","url_meta":{"origin":1175,"position":1},"title":"Drug Dealers vs Software Developers","author":"Wade","date":"September 18, 2009","format":false,"excerpt":"Drug dealers Software developers Refer to their clients as \"users\". Refer to their clients as \"users\". \"The first one's free!\" \"Download a free trial version...\" Have important South-East Asian connections (to help move the stuff). Have important South-East Asian connections (to help debug the code). Strange jargon: \"Stick\", \"Rock\", \"Dime\u2026","rel":"","context":"In &quot;Random Stuff&quot;","block_context":{"text":"Random Stuff","link":"https:\/\/wade.one\/blog\/category\/random-stuff\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1106,"url":"https:\/\/wade.one\/blog\/2023\/03\/26\/google-bard-php-developer-viewpoint\/","url_meta":{"origin":1175,"position":2},"title":"Google Bard &#8211; PHP developer viewpoint","author":"Wade","date":"March 26, 2023","format":false,"excerpt":"So I asked Bard to give me a reason to help me as as PHP developer then digged in to each point. Here's the answers and when I tried: Bard can help a PHP developer in a number of ways, including (wht: Code generation:\u00a0Bard can generate code in a variety\u2026","rel":"","context":"In &quot;AI&quot;","block_context":{"text":"AI","link":"https:\/\/wade.one\/blog\/category\/ai\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1109,"url":"https:\/\/wade.one\/blog\/2023\/03\/26\/php-8-2-vs-7-4\/","url_meta":{"origin":1175,"position":3},"title":"PHP 8.2 vs 7.4","author":"Wade","date":"March 26, 2023","format":false,"excerpt":"PHP is a widely used programming language that has been evolving rapidly in recent years. PHP 8.2 is the latest release, which came out on November 25th, 2021. This version brings several improvements, new features, and bug fixes, making it more efficient and secure than PHP 7.4. In this blog\u2026","rel":"","context":"In &quot;PHP&quot;","block_context":{"text":"PHP","link":"https:\/\/wade.one\/blog\/category\/php\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":671,"url":"https:\/\/wade.one\/blog\/2013\/12\/09\/phantomjs-custom-module-require-and-create\/","url_meta":{"origin":1175,"position":4},"title":"phantomjs custom module &#8211; require and create","author":"Wade","date":"December 9, 2013","format":false,"excerpt":"Recently I've been working with phantomjs\u00a0in order to do some on-page control without wanting to use an actual browser (phantomjs is headless and requires no X server to be running). One of the first things I wanted to do was created custom modules so I could organise my code clearly.\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/wade.one\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1158,"url":"https:\/\/wade.one\/blog\/2026\/03\/26\/why-senior-engineers-still-matter-more-in-the-ai-era\/","url_meta":{"origin":1175,"position":5},"title":"Why Senior Engineers Still Matter More in the AI Era","author":"Wade","date":"March 26, 2026","format":false,"excerpt":"AI can generate code faster, but that only makes direction, judgment, and accountability more important. Senior engineers still matter because the expensive mistakes are rarely typing mistakes.","rel":"","context":"In &quot;AI&quot;","block_context":{"text":"AI","link":"https:\/\/wade.one\/blog\/category\/ai\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1175","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/comments?post=1175"}],"version-history":[{"count":1,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1175\/revisions"}],"predecessor-version":[{"id":1198,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1175\/revisions\/1198"}],"wp:attachment":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/media?parent=1175"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/categories?post=1175"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/tags?post=1175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}