Generics and Collections, Chapter 5 Java implements generics via erasure, which ensures that legacy and generic versions usually generate identical class files, save for some auxiliary information about types. It is possible to replace a legacy class file by a generic class file without changing, or even recompiling, any client code; this is called binary compatibility.
Generics and Collections, Chapter 5 Java implements generics via erasure, which ensures that legacy and generic versions usually generate identical class files, save for some auxiliary information about types. It is possible to replace a legacy class file by a generic class file without changing, or even recompiling, any client code; this is called binary compatibility. Write once, run anywhere!!
{ } public class Dog implements Animal{ } public class App { public static void main(String[] args) { ArrayList<Animal> animals = new ArrayList<Dog>(); // Error! ArrayList<? extends Animal> animals = new ArrayList<Dog>(); } }
trait Animal scala> class Dog extends Animal defined class Dog scala> val dogs = List(new Dog) dogs: List[Dog] = List(Dog@51da6868) scala> val animals:List[Animal] = dogs animals: List[Animal] = List(Dog@51da6868)
if (m <:< manifest[String]) println("Hey, this list is full of strings") else println("Non-stringy list") } foo(List("one", "two")) // Hey, this list is full of strings foo(List(1, 2)) // Non-stringy list foo(List("one", 2)) // Non-stringy list cf. http://stackoverflow.com/questions/3213510/what-is-a-manifest-in-scala-and-when-do-you-need-it
{ typeOf[A] match { case t if t =:= typeOf[String] => println("Hey, this list is full of strings") case _ => println("Non-stringy list") } } foo(List("one", "two")) // Hey, this list is full of strings foo(List(1, 2)) // Non-stringy list foo(List("one", 2)) // Non-stringy list