Java Interoperability
Prerequisites: Working with files
Scala compiles to JVM bytecode, so every Java library works directly.
Using Java classes
import java.time.{LocalDate, Period, DayOfWeek}
import java.util.UUID
@main def javaClasses(): Unit =
val start = LocalDate.of(2025, 1, 15)
val end = LocalDate.of(2025, 4, 22)
println(Period.between(start, end))
println(end.plusDays(10))
println(end.getDayOfWeek == DayOfWeek.TUESDAY)
println(UUID.nameUUIDFromBytes("ada".getBytes).toString.length)
println(String.join(", ", "a", "b"))
P3M7D
2025-05-02
true
36
a, b
Converting collections
Java APIs return Java collections; convert at the boundary:
import scala.jdk.CollectionConverters.*
@main def converters(): Unit =
val javaList = java.util.ArrayList[String]()
javaList.add("x")
javaList.add("y")
val scalaList: List[String] = javaList.asScala.toList
println(scalaList.map(_.toUpperCase))
val backToJava: java.util.List[Int] = List(1, 2, 3).asJava
println(backToJava.size())
println(Map("a" -> 1).asJava.get("a"))
List(X, Y)
3
1
null from Java
Java methods may return null. Wrap such results in Option(...), which
turns null into None:
@main def nulls(): Unit =
val env = System.getenv("SURELY_NOT_SET_12345")
println(env)
println(Option(env).getOrElse("default"))
println(Option(System.getProperty("java.version")).isDefined)
null
default
true
Calling Scala from Java
Scala classes are visible to Java too. A few tips keep them friendly:
use @main or an object with def main, annotate varargs methods with
@varargs, avoid Scala-only features (like default parameters and
givens) in public APIs meant for Java, and offer Java collection types at
the boundary.
What's next
Try the Intermediate Projects, then continue to Level 3 — Advanced: givens and type classes, advanced types, concurrency, and production Scala.