Skip to main content

CSE 331: Generics

A generic class or interface declares one or more type parameters in angle brackets after its name, and code that uses it writes a type argument there, as in ListQueue<String>. The type argument is a claim about every element, and javac checks it at every call. javac confirms type safety one line at a time: on every run, a variable refers only to objects of its declared type. So a queue of Strings needs no cast, where a queue of Objects needs a cast that can fail when the program runs. Inside a generic class, the code may call on an E only the methods of Object. A bound, as in <P extends Product>, lets the code use a P as a Product, and a method may declare a type parameter itself. javac does not accept a List<SaleProduct> where a List<Product> is expected, though every SaleProduct is a Product: the add of a list of sale products takes only a SaleProduct, a stronger precondition, so that list is not a behavioral subtype. Java gave arrays the other answer, and checks each store into an array of objects when the program runs. A wildcard asks for less: a List<? extends Product> can be read from, and its add accepts nothing but null, and a List<? super SaleProduct> can be added to, while an element read from it is known only to be an Object. javac leaves the type arguments out of the code that runs, which is called type erasure, so instanceof cannot check one.