Search code examples
scalatypeslistbuffer

Why isn't a ListBuffer with String and Date elements ListBuffer[Any]?


Let's say I've got:

var pairOfObjects = ListBuffer("", myDate)

Where myDate is of type java.util.Date, and it's value is 1970-01-01T00:00:00.000-00:00

Putting that into the Scala REPL tells me: pairOfObjects: scala.collection.mutable.ListBuffer[Comparable[_ >: java.util.Date with String <: Comparable[_ >: java.util.Date with String <: java.io.Serializable] with java.io.Serializable] with java.io.Serializable] = ListBuffer("", Wed Dec 31 16:00:00 PST 1969)

I'd expect it to be something like ListBuffer[Any]. In fact, when I put in:

var pairOfObjects = ListBuffer("", 1)

The Scala REPL does give me:

pairOfObjects: scala.collection.mutable.ListBuffer[Any] = ListBuffer("", 1)

Why does putting in a Date object to the ListBuffer result in such a complicated type?


Solution

  • A List in Scala is covariant.

    Example for Int and Double are subtypes of Double, then List[Int] and List[Double] are also subtypes of List[Double].

    Here is the definition for string in scala from Predef object

    type String = java.lang.String
    

    Java String class declartion

    public final class String
    extends Object
    implements Serializable, Comparable<String>, CharSequence
    

    java.util.date class declartion

    public class Date
    extends Object
    implements Serializable, Cloneable, Comparable<Date>
    

    Now after looking into these definitions both Date and String class in java are inherited classes from java.io.Serializable and not from Any directly so you don't see ListBuffer[Any] when the list elements are Date and String.

    Thereby from these statement

    scala.collection.mutable.ListBuffer[Comparable[_ >: java.util.Date with String <: Comparable[_ >: java.util.Date with String <: java.io.Serializable] with java.io.Serializable] with java.io.Serializable] = ListBuffer("", Wed Dec 31 16:00:00 PST 1969)

    Any is lower type bound to java.util.date with String which are upper bound to java.io.Serializable