Download presentation
Presentation is loading. Please wait.
Published byMyles Hunter Modified over 9 years ago
1
Generics CompSci 230 S2 2015 Software Construction
2
Agenda & Reading Topics: Introduction Fundamentals of generic types Generics & Subtyping Type wildcards Reading The Java Tutorial: Generics Generics 092
3
What Are Generics? Generics abstract over Types Classes, Interfaces and Methods can be Parameterized by Types Generics provide increased readability and type safety 093
4
Example: Item BookMovieCD Priced > Shirt public class Item { protected String title; public Item(String title) { this.title = title; } public String getTitle() { return title; } public class Book extends Item { private String author; public Book(String title, String author) { super(title); this.author = author; }... public String toString() { return "Book: '" +... } public class Movie extends Item { private int year; public Movie(String title, int year) { super(title); this.year = year; }... public String toString() { return... } public class CD extends Item implements Priced { private double price;... public doublegetPrice() {...} } public interface Priced { public double getPrice(); } 094
5
Interface java.util.List Java’s original specification for list data structures (non-generic – Java 1.4) This interface defines a contract for each of the operations of a list, i.e. What it takes in What it returns What the state of the list should be afterwards Individual implementations should fulfil the contract – in whatever way they see fit public interface List { public boolean add(Object o); public boolean add(int i, Object); public Object remove(int i); public Object remove(Object o); public Object get(int i); public int indexOf(Object o); public boolean contains(Object o); public int size(); public Iterator iterator(); //plus others } 095
6
Why generics? Type Safety! Array: We must say what’s in the array ArrayList: But anything could go in the ArrayList; We can pass in Movie, Book and CD instances as arguments to add( ) as its formal argument type is Object However because get( )’s return type is Object, we need to downcast the result to the appropriate subclass Person[] people = new Person[25]; people[0] = "Sally"; // syntax error ArrayList people = new ArrayList(); people.add("Sally"); List items = new ArrayList(); items.add(new Movie("Psycho",1960)); items.add(new Book("LOTR","Toklien")); for (int i = 0; i < items.size(); i++) { Item item = (Item)items.get(i); System.out.println(i+": "+item.getTitle()); } 096
7
List of Items We want items to store only objects of type Item (or its subclasses) What happens if it doesn't? What exactly would happen? Will this compile? Will it run? items.add(new Movie("Psycho",1960)); items.add("Terminator"); for (int i = 0; i < items.size(); i++) { Item item = (Item)items.get(i); System.out.println(i+": "+item.getTitle()); } Runtime error Example: TestsApp 097
8
Compile-time vs. Runtime errors Moral of the story: we can’t rely on the compiler to detect/predict all errors (although we’d like to) What compilers can detect: Syntactic/”obvious” errors, e.g: accessing an undeclared variable; calling an undefined method; mismatching braces/brackets; assigning a value to a variable of incompatible type What compilers can't: Logical errors, unexpected behaviours only observable at runtime e.g. accessing a null field, bogus user input, nondeterministic code Most lead to exceptions being thrown like NullPointerException, ArrayIndexOutOfBoundsException, NumberFormatException, ClassCastException 098
9
What can we do instead? Create a specialised List for Item? NO! Repetitive Inefficient Hardly scalable public class ItemList { private List items; public ItemList() { items = new ArrayList(); }... } public class StringList { private List items; public StringList () { items = new ArrayList(); } public void add(String s) { items.add(s); }... } public class IntList { private List items; public IntList() { items = new ArrayList(); } public void add(Integer i) { items.add(i); }... } 099
10
Answer: Generics! With generics, we can make List a generic type By parameterising List with the type Item we are guaranteed that any instance of this special List would only contain objects of type T (or its subclasses) 0910
11
Example: Instead of saying: List words = new ArrayList(); You'll have to say: Replaces runtime type checks with compile-time checks No casting; instead of String title = (String) words.get(i); you use Some classes and interfaces that have been “genericized” are: Vector, ArrayList, LinkedList, Hashtable, HashMap, Stack, Queue … List words = new ArrayList (); String title = words.get(i); 0911
12
More Examples The letter E as the type parameter for elements in generic collections Examples: ArrayList words = new ArrayList (); ArrayList nums = new ArrayList (); ArrayList words = new ArrayList (); list1.add(new String("HA")); list1.add(new String("HE"));; String s1 = list1.get(0); String s2 = list1.get(1); System.out.println(s1 + " " + s2); ArrayList nums = new ArrayList (); nums.add(new Integer(4)); nums.add(new Integer(5)); Integer i1 = nums.get(0); Integer i2 = nums.get(1); 0912
13
for-each loop The for-each loop is used to access each successive value in a collection of values. Syntax: Example: ArrayList words = new ArrayList ();... for (String str : words) { System.out.println(str); } for (Base_Type var :Collection_Object) Statement; 0913
14
Generics and type safety Good news: the compiler can help us prevent type errors The compiler enforces the parameterised type List to only accept and return instances of Item (or its subclasses) List genericsItems = new ArrayList (); genericsItems.add(new Movie("Psycho",1960)); genericsItems.add("Terminator"); List genericsItems = new ArrayList (); genericsItems.add(new Movie("Psycho",1960)); genericsItems.add(new Book("LOTR","Tolkien")); genericsItems.add(new CD("Ozomatli",2.50)); for (int i = 0; i < genericsItems.size(); i++) { Item item = genericsItems.get(i); System.out.println(i+": "+item.getTitle()); } COMPILE-TIME ERROR Example: TestGenericsApp 0914
15
Generics Vs No Generics public class Arraylist { private E[] elementData;... //stuff public boolean add(E o) { elementData[size++] = o; return true; } public E get(int i) { return elementData[i]; } public class ArrayList { private Object[] elementData;... //stuff public boolean add(Object o) { elementData[size++] = o; return true; } public Object get(int i) { return elementData[i]; } ‘Generic type’ ‘Non-generic type’ ArrayList items = new ArrayList (); ‘Type argument’ ‘Parameterised type’ ‘Type parameter’ /‘Type variable’ 0915
16
Example: Comparable + Generics Comparable Interface: java.lang.Comparable int compareTo() returns an integer result: Returns negative if the object it is applied to is less than the argument Returns zero if the object it is applied to is equal to the argument Returns positive if the object it is applied to is greater than the argument public interface Comparable { public int compareTo(Object obj); } public class Person implements Comparable { protected String irdNumber;... public int compareTo(Object obj) { if (!(obj instanceof Person)) { throw new ClassCastException("Not a Person"); } Person p = (Person) obj; return irdNumber.compareTo(p.getIRD()); } without Generics public class Person implements Comparable protected String irdNumber;... public int compareTo(Person p) { return irdNumber.compareTo(p.getIRD()); } with Generics 0916
17
Generics & Subtyping Is a List of String a List of Object? Is a List of Movie a List of Item? If this is allowed, then we can add items to the list of Movie by accessing genericsItems attempt to assign an Item to a Movie object!!! List ls = new ArrayList (); ls.add("Hello");... List lo = ls; List lm = new ArrayList (); lm.add(new Movie("Psycho",1960));... genericsItems = lm; COMPILE-TIME ERROR genericsItems.add(new Item("Sample")); Movie m1 = lm.get(0); ERROR 0917
18
Generics & Subtyping So Movie is a subtype of Item, and G is some generic type declaration It is not the case that G is a subtype of G But We normally think that a List is a List assuming that Drive is a subtype of Person. We will need to look at Wildcards! 0918
19
Type wildcards Here’s a simple (no generics) method to print out any list (without generics): The above still works in Java 1.5, but now it generates warning messages Next, here is an attempt using Generics But it only takes a list of Object, but it is not a supertype of all kinds of lists. public static void printCollection(List c) { for (Iterator i = c.iterator(); i.hasNext(); ) { System.out.println(i.next()); } public static void printCollection(List c) { for (Iterator i = c.iterator(); i.hasNext(); ) { System.out.println(i.next()); } uses unchecked or unsafe operations. Note: Recompile with - Xlint:unchecked for details. List mylist = new ArrayList(); … printCollection(mylist); List mylist = new ArrayList (); printCollection(mylist); //ERROR 0919
20
Type wildcards You should eliminate all errors and warnings in your final code, so you need to tell Java that any type is acceptable: (i.e. any type) signifies an unbounded wildcard. (pronounced “list of unknown”) a list whose element type matches anything = called wildcard type public static void printCollection(List c) { for (Iterator i = c.iterator(); i.hasNext(); ) { System.out.println(i.next()); } List movieList = new ArrayList (); movieList.add(new Movie("Psycho",1960)); printCollection(movieList); List myStrlist = new ArrayList (); myStrlist.add("Hello"); printCollection(myStrlist); 0920
21
for-each statement for( type var : array) {...} or for( type var : collection ) {...} Example: public static void printCollection(List c) { for (Object e: c) { System.out.println(e); } List movieList = new ArrayList (); movieList.add(new Movie("Psycho",1960)); printCollection(movieList); List myStrlist = new ArrayList (); myStrlist.add("Hello"); printCollection(myStrlist); 0921
22
Subtyping in generics Consider the following method: The type rules say that the above method can only be called on lists of exactly Item: It cannot, for instance, be called on a List But, how to accept a list of any kind of item (e.g. List, List ) Item Movie public static void printItemCollection(List il) { for (Item i: il) { System.out.println(i.getTitle()); } public static void printItemCollection(List il) { for (Item i: il) { System.out.println(i.getTitle()); } 0922
23
Bounded Wildcards (i.e. any subclass of T, including T itself) signifies a bounded wildcard (i.e. any type) signifies an unbounded wildcard Note: is equivalent to => Item is the upper bound of the wildcard Note that since wildcards denote unknown types, there are limitations on how a wildcard variable can be used It is now illegal to write into the list in the body of the method Such limitations are compiler enforced It is an unknown subtype of Item. Since we don’t know what type it is, we don’t know if it is a supertype of Movie; it might or might not be such a supertype, so it isn’t safe to pass a Movie there. public static void printItemCollection(List il) { il.add(new Movie("Psycho",1960)); } COMPILE-TIME ERROR 0923
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.