CSCE 314 Lecture 28

From Notes
Jump to navigation Jump to search

« previous | Monday, November 7, 2011 | next »


Java Basics

Typesafe polymorphic containers:

Every class extends the base/root Object class.

Generics

Allow us to parameterize types for classes and methods (type parameterization is almost identical to templates in C++)

C++ rewrites code filling in the parameters, but Java compiler maintains each parameter as an Object type and casts variables to specified types.


Without Generics/Templates

List l = new LinkedList()
l.add(new Integer(0));
Integer x = (Integer) l.iterator().next();
String s = (String) l.iterator().next(); // bad cast exception

With Generics/Templates

List<Integer> l = new LinkedList<Integer>()
l.add(new Integer(0));
Integer x = l.iterator().next();
String s = l.iterator().next(); // compile time error


Parameterized Method Example

public class ArrayUtil
{
    // ...
    public static <E> void print(E[] a)
    {
        for (E e : a) System.out.print(e.toString() + " ");
        System.out.println();
    }
}

Rectangle[] rects = // ...
String[] strs = // ...

// can be used either way
ArrayUtil.<Rectangle>print(rects);
ArrayUtil.print(strs);

Notice that there is a toString method assumed on all Objects. In Haskell, we had to explicitly state that a has to be of type class Show:

print :: [a] -> IO ()
print ls = sequence (map (putStr . show) ls) >> return () -- ERROR!

print :: Show a => [a] -> IO ()
print ls = sequence (map (putStr . show) ls) >> return () -- This is OK


Bounds on Generics

Provides constraints on types that can be used in generic templates:

class SortedClass<T extends Comparable & Serializable> { /* ... */ } !a!D


Wildcards

static void printAll(List<?> l) {
    for (Object o : l) System.out.println(o);
}