Scala String.format error: overloaded method value format with alternatives

I was writing some Scala StringBuilder code like this today:

val sb = new StringBuilder
for (b: Byte <- mdOut.digest) {
    val hexString: String = String.format("%02x", b)
    sb.append(hexString)
}
sb.toString

and encountered this error message:

Error:(40, 44) overloaded method value format with alternatives:
  (x$1: java.util.Locale,x$2: String,x$3: Object*)String <and>
  (x$1: String,x$2: Object*)String
 cannot be applied to (String, Byte)
            val hexString: String = String.format("%02x", b)

The problem

In short, it turns out that the problem is that the Byte value I’m using here is the scala.Byte value, which is a wrapper around the primitive byte in Java and a descendant of scala.AnyValue. Because Scala.byte is not a descendant of the Java Object class, the second (overloaded) method signature doesn’t apply to what I’m trying to do. In Scala terms, here’s what that second String.format method signature expects:

(x1: String, x2: java.lang.Object*): String
             ---------------------

And this is what I’m trying to pass into it:

(x1: String, x2: scala.Byte): String
             --------------

The solution

The solution to the problem is to “box” the byte value. This converts the scala.Byte value into a Java Byte object that I can pass into String.format. When working with a Scala Byte value you do this with the Byte.box() method (a box method on the Scala Byte object). Here’s the solution:

val sb = new StringBuilder
for (b: Byte <- mdOut.digest) {
    val hexString: String = String.format("%02x", Byte.box(b))  //notice Byte.box
    sb.append(hexString)
}
sb.toString

When you compile that code you’ll see that it works without any errors; problem solved.

Discussion: Scala boxing methods

The Byte class scaladoc states that the box method “Transforms a value type into a boxed reference type,” and further states the box method return type is a java.lang.Byte.

To further understand the problem, if you look at the scala.Byte scaladoc, you’ll find its description as follows: “Byte, an 8-bit signed integer (equivalent to Java’s byte primitive type) is a subtype of scala.AnyVal. Instances of Byte are not represented by an object in the underlying runtime system.”

If you run into this error message with other Scala data types, you’ll find that they all offer box methods to convert them into descendants of the Java Object class. For instance, you’ll find box methods on each of these scaladoc pages:

In summary, if you run into this “overloaded method value format with alternatives” error message when using String.format, I hope this information is helpful.