{"id":168,"date":"2024-06-30T06:28:00","date_gmt":"2024-06-30T04:28:00","guid":{"rendered":"https:\/\/codeswarm.io\/?p=168"},"modified":"2026-07-24T08:35:18","modified_gmt":"2026-07-24T06:35:18","slug":"java-17-lts-through-the-eyes-of-scala-developer","status":"publish","type":"post","link":"https:\/\/codeswarm.io\/?p=168","title":{"rendered":"Java 17 LTS through the eyes of Scala developer"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Java and Scala are both modern, powerful languages that offer a range of features for developers, and while they differ in their paradigms (Java being primarily object-oriented and Scala being a hybrid of object-oriented and functional programming), they do share some similarities, especially as both languages have evolved. As an experienced Java developer (from Java 7 to the latest) and also experienced Scala developer I will try to compare the two languages.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Immutability<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Immutability in Java refers to the design of objects whose state cannot be modified after they are created. Once an immutable object is instantiated, its fields cannot be changed, which provides several advantages, including thread safety, simplicity, and easier debugging. The most well-known immutable class in Java is <code>String<\/code>, but developers can create their own immutable classes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Java 17<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public record Person(String name, int age) {}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Records automatically generate:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>constructor,<\/li>\n\n\n\n<li>getters,<\/li>\n\n\n\n<li>equals(),<\/li>\n\n\n\n<li>hashCode(),<\/li>\n\n\n\n<li>toString().<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">However, records provide <strong>shallow immutability<\/strong>.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">record Team(List&lt;String> members) {}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The reference cannot change, but the list can.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Scala 2.13<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">case class Person(name: String, age: Int)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Case classes are immutable by convention.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">val p = Person(\"John\", 30)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Fields are <code>val<\/code> unless explicitly declared <code>var<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Scala 3<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Same concept, with additional compiler improvements.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Sealed Types<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Sealed types restrict who may extend a hierarchy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Java 17<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">sealed interface Shape\n    permits Circle, Rectangle {}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Useful for exhaustive pattern matching.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Scala 2.13<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">sealed trait Shape\ncase class Circle(r: Double) extends Shape\ncase class Rectangle(w: Double,h: Double) extends Shape<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">All subclasses must be in the same source file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Scala 3<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Exactly the same idea.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Scala 3 enums automatically create sealed hierarchies.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Pattern Matching<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Pattern matching allows branching based on structure, not just type.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Java 17<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">if (obj instanceof String s) {\n    System.out.println(s.length());\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Switch pattern matching was still a preview feature.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Scala 2.13<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">shape match {\n    case Circle(r) => ...\n    case Rectangle(w,h) => ...\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Can match:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>values<\/li>\n\n\n\n<li>types<\/li>\n\n\n\n<li>tuples<\/li>\n\n\n\n<li>lists<\/li>\n\n\n\n<li>nested objects<\/li>\n\n\n\n<li>regex<\/li>\n\n\n\n<li>custom extractors<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Scala&#8217;s pattern matching is far more expressive.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Type Inference<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Type inference lets the compiler determine types automatically.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Java<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">var list = List.of(1,2,3);<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Only local variables.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Scala<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">val list = List(1,2,3)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Inference works for<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>methods<\/li>\n\n\n\n<li>lambdas<\/li>\n\n\n\n<li>generic types<\/li>\n\n\n\n<li>pattern matching<\/li>\n\n\n\n<li>collections<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Scala 3 further improves inference.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Lambdas<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Lambdas represent anonymous functions.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Java<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">list.stream()\n    .map(x -> x * 2)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Requires functional interfaces.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Scala<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">list.map(_ * 2)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Functions are true objects.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Collections<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Collections are central to functional programming.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Java<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Uses<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>List<\/li>\n\n\n\n<li>Set<\/li>\n\n\n\n<li>Map<\/li>\n\n\n\n<li>Stream<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Streams are separate from collections.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Scala<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Everything supports<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">map\nflatMap\nfilter\ncollect\ngroupBy\npartition\nfold\nreduce\nscan<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">without converting to streams.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Functional Programming<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Functional programming emphasizes pure functions, immutable data, and function composition.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Java supports FP, but Scala is designed around it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Scala libraries:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Cats<\/li>\n\n\n\n<li>Cats Effect<\/li>\n\n\n\n<li>ZIO<\/li>\n\n\n\n<li>FS2<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">make purely functional programming practical.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">8. Optional vs Option<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Both represent optional values.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Java<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Optional&lt;String><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Designed mainly for return types.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Scala<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Option[String]<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Behaves like a collection.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">option.map(...)\noption.flatMap(...)\noption.filter(...)<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">9. Null Safety<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Null references are a common source of runtime errors.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Java<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">String s = null;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Perfectly legal.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Scala 2<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Prefer<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Option[String]<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">instead of null.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Scala 3<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">With Explicit Nulls<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">String<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">String | Null<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">are different types.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Much safer.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">10. Exceptions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Exception handling reports errors during execution.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Java<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>checked exceptions<\/li>\n\n\n\n<li>unchecked exceptions<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Compiler forces checked exceptions.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Scala<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Only unchecked exceptions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Functional libraries usually avoid exceptions entirely by using:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Try<\/code><\/li>\n\n\n\n<li><code>Either<\/code><\/li>\n\n\n\n<li><code>IO<\/code><\/li>\n\n\n\n<li><code>ZIO<\/code><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">11. Algebraic Data Types (ADT)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">ADTs model complex domains by combining product types (AND) and sum types (OR).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Java<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">sealed interface Expr {}\n\nrecord Num(int value) implements Expr {}\nrecord Add(Expr l, Expr r) implements Expr {}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Scala<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">sealed trait Expr\n\ncase class Num(v:Int) extends Expr\ncase class Add(l:Expr,r:Expr) extends Expr<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Scala 3<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">enum Expr:\n  case Num(v:Int)\n  case Add(l:Expr,r:Expr)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Scala offers much more concise ADT support.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">12. Higher-Order Functions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Higher-order functions either accept functions as parameters or return functions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Java:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">list.forEach(System.out::println);<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Scala:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">list.foreach(println)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Higher-order functions are fundamental in Scala.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">13. Implicits<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Implicits allow values or conversions to be supplied automatically by the compiler.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Scala 2:<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">implicit val ec = ExecutionContext.global<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Scala 3<\/strong> replaces this with clearer syntax:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">given ExecutionContext = ExecutionContext.global\n\ndef run(using ExecutionContext)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Java<\/strong> has no comparable language feature.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">14. Extension Methods<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Extension methods add behavior to existing types without inheritance.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Java uses utility classes:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Collections.sort(list);<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Scala 2<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">implicit class RichString(s: String)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Scala 3<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">extension (s: String)\n  def hello = ...<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is now a first-class language feature.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">15. Value Classes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Value classes wrap existing types without (in many cases) introducing runtime allocation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Scala 2:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class UserId(val value: Long) extends AnyVal<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Scala 3 favors opaque types:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"scala\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">opaque type UserId = Long<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">These provide type safety with effectively zero runtime overhead.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Java has no direct equivalent in Java 17 (Project Valhalla aims to introduce value objects in a future release).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">16. Type System<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A language&#8217;s type system determines how expressive and safe programs can be.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Java offers:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>generics<\/li>\n\n\n\n<li>wildcards<\/li>\n\n\n\n<li>bounded types<\/li>\n\n\n\n<li>sealed types<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Scala additionally supports:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>higher-kinded types<\/li>\n\n\n\n<li>variance annotations<\/li>\n\n\n\n<li>path-dependent types<\/li>\n\n\n\n<li>abstract type members<\/li>\n\n\n\n<li>type classes<\/li>\n\n\n\n<li>dependent function types (Scala 3)<\/li>\n\n\n\n<li>union types (Scala 3)<\/li>\n\n\n\n<li>intersection types (Scala 3)<\/li>\n\n\n\n<li>match types (Scala 3)<\/li>\n\n\n\n<li>opaque types (Scala 3)<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Scala&#8217;s type system is among the most expressive of mainstream programming languages.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">17. Compilation Speed<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Compilation speed affects developer productivity, especially in large codebases.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Java 17:<\/strong> Fastest compilation due to a simpler type system and mature incremental compilation.<\/li>\n\n\n\n<li><strong>Scala 2.13:<\/strong> Noticeably slower because the compiler performs advanced type inference and implicit resolution.<\/li>\n\n\n\n<li><strong>Scala 3:<\/strong> Improves compiler architecture and is often faster than Scala 2.13, though still generally slower than Java for comparable projects.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">18. Learning Curve<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The learning curve reflects how quickly developers become productive.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Java 17:<\/strong> Gentle learning curve. A developer can become productive quickly thanks to a relatively small language surface and consistent syntax.<\/li>\n\n\n\n<li><strong>Scala 2.13:<\/strong> Steep learning curve. Besides object-oriented programming, developers must understand functional programming concepts, advanced collections, implicits, and a sophisticated type system.<\/li>\n\n\n\n<li><strong>Scala 3:<\/strong> Still challenging, but easier than Scala 2.13. The redesigned syntax, <code>given<\/code>\/<code>using<\/code> mechanism, extension methods, enums, and improved error messages reduce much of the accidental complexity while preserving Scala&#8217;s expressive power.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Overall comparison<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Choose Java 17<\/strong> if you value simplicity, fast compilation, broad industry adoption, and ease of maintenance.<\/li>\n\n\n\n<li><strong>Choose Scala 2.13<\/strong> if you work on existing Scala ecosystems (e.g., Spark, Akka Classic, Play Framework) and need maximum compatibility.<\/li>\n\n\n\n<li><strong>Choose Scala 3<\/strong> if you want the full expressive power of Scala with a cleaner language design, stronger type safety, modern features such as enums, opaque types, union types, and native extension methods, and are starting a new Scala project.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Java and Scala are both modern, powerful languages that offer a range of features for developers, and while they differ in their paradigms (Java being primarily object-oriented and Scala being a hybrid of object-oriented and functional programming), they do share some similarities, especially as both languages have evolved. As an experienced Java developer (from &hellip; <a href=\"https:\/\/codeswarm.io\/?p=168\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Java 17 LTS through the eyes of Scala developer<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23],"tags":[18,19],"class_list":["post-168","post","type-post","status-publish","format-standard","hentry","category-programming","tag-java","tag-scala"],"_links":{"self":[{"href":"https:\/\/codeswarm.io\/index.php?rest_route=\/wp\/v2\/posts\/168","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codeswarm.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codeswarm.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codeswarm.io\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codeswarm.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=168"}],"version-history":[{"count":11,"href":"https:\/\/codeswarm.io\/index.php?rest_route=\/wp\/v2\/posts\/168\/revisions"}],"predecessor-version":[{"id":179,"href":"https:\/\/codeswarm.io\/index.php?rest_route=\/wp\/v2\/posts\/168\/revisions\/179"}],"wp:attachment":[{"href":"https:\/\/codeswarm.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codeswarm.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=168"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codeswarm.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}