Modulo I Java – Genericswebserver2.tecgraf.puc-rio.br/~ismael/Cursos/Cidade_DSOO/aulas/... · 6...

35
1 April 05 Prof. Ismael H. F. Santos - [email protected] 1 Modulo I Java – Generics Prof. Ismael H F Santos April 05 Prof. Ismael H. F. Santos - [email protected] 2 Ementa Modulo I - Tópicos em JAVA Generics (incompleto !)

Transcript of Modulo I Java – Genericswebserver2.tecgraf.puc-rio.br/~ismael/Cursos/Cidade_DSOO/aulas/... · 6...

1

April 05 Prof. Ismael H. F. Santos - [email protected] 1

Modulo I Java – Generics

Prof. Ismael H F Santos

April 05 Prof. Ismael H. F. Santos - [email protected] 2

Ementa

Modulo I - Tópicos em JAVAGenerics (incompleto !)

2

April 05 Prof. Ismael H. F. Santos - [email protected] 3

Linguagem de Programação JAVAIsmael H. F. Santos, Apostila UniverCidade, 2002

The Java Tutorial: A practical guide for programmersTutorial on-line: http://java.sun.com/docs/books/tutorial

Java in a NutshellDavid Flanagan, O´Reilly & Associates

Just Java 2Mark C. Chan, Steven W. Griffith e Anthony F. Iasi, Makron

Books.Java 1.2

Laura Lemay & Rogers Cadenhead, Editora Campos

Bibliografia

April 05 Prof. Ismael H. F. Santos - [email protected] 4

LivrosCore Java 2, Cay S. Horstmann, Gary Cornell

Volume 1 (Fundamentos)Volume 2 (Características Avançadas)

Java: Como Programar, Deitel & DeitelThinking in Patterns with JAVA, Bruce Eckel

Gratuito. http://www.mindview.net/Books/TIJ/

3

April 05 Prof. Ismael H. F. Santos - [email protected] 5

GenericsPOO-Java

April 05 Prof. Ismael H. F. Santos - [email protected] 6

Concepts

Generalizing Collection ClassesUsing Generics with other Java 1.5 FeaturesIntegration of Generics with Previous ReleasesUser built generic classes

4

April 05 Prof. Ismael H. F. Santos - [email protected] 7

What Are Generics?

Generics abstract over TypesClasses, Interfaces and Methods can be Parameterized by TypesGenerics provide increased readability and type safety

April 05 Prof. Ismael H. F. Santos - [email protected] 8

Java Generic Programming

Java has class ObjectSupertype of all object typesThis allows “subtype polymorphism”

Can apply operation on class T to any subclass S <: TJava 1.0 – 1.4 do not have templates

No parametric polymorphismMany consider this the biggest deficiency of Java

Java type system does not let you cheatCan cast from supertype to subtypeCast is checked at run time

5

April 05 Prof. Ismael H. F. Santos - [email protected] 9

A class definition with a type parameter is stored in a file and compiled just like any other class.

Once a parameterized class is compiled, it can be used like any other class.

However, the class type plugged in for the type parameter must be specified before it can be used in a program.

Doing this is said to instantiate the generic class.

Sample<String> object = new Sample<String>();

Generics (Cont’d)

April 05 Prof. Ismael H. F. Santos - [email protected] 10

A Class Definition with a Type Parameter

6

April 05 Prof. Ismael H. F. Santos - [email protected] 11

A class that is defined with a parameter for a type is called a generic class or a parameterized class

The type parameter is included in angular brackets after the class name in the class definition heading.

Any non-keyword identifier can be used for the type parameter, but by convention, the parameter starts with an uppercase letter.

The type parameter can be used like other types used in the definition of a class.

A Class Definition with a Type Parameter (Cont’d)

April 05 Prof. Ismael H. F. Santos - [email protected] 12

Tip: Compile with the -Xlint Option

There are many pitfalls that can be encountered when using type parameters

Compiling with the -Xlint option will provide more informative diagnostics of any problems or potential problems in the code

javac –Xlint Sample.java

7

April 05 Prof. Ismael H. F. Santos - [email protected] 13

Example generic construct: Stack

Stacks possible for any type of objectFor any type t, can have type stack_of_tOperations push, pop work for any type

In C++, would write generic stack classtemplate <type t> class Stack {

private: t data; Stack<t> * next;public: void push (t* x) { … }

t* pop ( ) { … } };

What can we do in Java?

April 05 Prof. Ismael H. F. Santos - [email protected] 14

Simple Example Using Interfaces

interface List<E> { void add(E x); Iterator<E> iterator();

}

interface Iterator<E> {E next();

boolean hasNext();}

8

April 05 Prof. Ismael H. F. Santos - [email protected] 15

What Generics Are Not

Generics are not templatesUnlike C++, generic declarations are

Typechecked at compile timeGenerics are compiled once and for all

Generic source code not exposed to userNo bloat

The type checking with Java 1.5 Generics changes the way one programs(as the next few slides show)

The type checking with Java 1.5 Generics The type checking with Java 1.5 Generics changes the way one programschanges the way one programs(as the next few slides show)(as the next few slides show)

April 05 Prof. Ismael H. F. Santos - [email protected] 16

Java 1.0 vs Generics

class Stack {void push(Object o) { ... }Object pop() { ... }...}

String s = "Hello";Stack st = new Stack(); ...st.push(s);...s = (String) st.pop();

class Stack<A> {void push(A a) { ... }A pop() { ... }...}

String s = "Hello";Stack<String> st =

new Stack<String>();st.push(s);...s = st.pop();

9

April 05 Prof. Ismael H. F. Santos - [email protected] 17

Generic Class Definition: An Example

April 05 Prof. Ismael H. F. Santos - [email protected] 18

Generic Class Definition: An Example (Cont’d)

10

April 05 Prof. Ismael H. F. Santos - [email protected] 19

Generic Class Usage: An Example

April 05 Prof. Ismael H. F. Santos - [email protected] 20

Generic Class Usage: An Example (Cont’d)

Program Output:

11

April 05 Prof. Ismael H. F. Santos - [email protected] 21

Java generics are type checked

A generic class may use operations on objects of a parameter type

Example: PriorityQueue<T> … if x.less(y) then …

Two possible solutionsC++: Link and see if all operations can be resolvedJava: Type check and compile generics w/o linking

This requires programmer to give information about type parameterExample: PriorityQueue<T extends ...>

April 05 Prof. Ismael H. F. Santos - [email protected] 22

How to Use Generics

List<Integer> xs = new LinkedList<Integer>();xs.add(new Integer(0));Integer x = xs.iterator.next();

Compare with

List xs = new LinkedList();xs.add(new Integer(0));Integer x = (Integer)xs.iterator.next();

12

April 05 Prof. Ismael H. F. Santos - [email protected] 23

A Generic Constructor Name Has No Type Parameter!!!

Although the class name in a parameterized class definition has a type parameter attached, the type parameter is not used in the heading of the constructor definition:

public Pair<T>()

A constructor can use the type parameter as the type for a parameter of the constructor, but in this case, the angular brackets are not used:

public Pair(T first, T second)

However, when a generic class is instantiated, the angular brackets are used:

Pair<String> pair= new Pair<STring>("Happy", "Day");

April 05 Prof. Ismael H. F. Santos - [email protected] 24

A Primitive Type Cannot be Plugged in for a Type Parameter!!!

The type plugged in for a type parameter must always be a reference type:

It cannot be a primitive type such as int, double, orchar

However, now that Java has automatic boxing, this is not a big restriction.

Note: Reference types can include arrays.

13

April 05 Prof. Ismael H. F. Santos - [email protected] 25

Limitations on Type Parameter Usage

Within the definition of a parameterized class definition, there are places where an ordinary class name would be allowed, but a type parameter is not allowed.

In particular, the type parameter cannot be used in simple expressions using new to create a new object

For instance, the type parameter cannot be used as a constructor name or like a constructor:

T object = new T();T[] a = new T[10];

April 05 Prof. Ismael H. F. Santos - [email protected] 26

Limitations on Generic Class Instantiation

Arrays such as the following are illegal:

Pair<String>[] a = new Pair<String>[10];

Although this is a reasonable thing to want to do, it is not allowed given the way that Java implements generic classes

14

April 05 Prof. Ismael H. F. Santos - [email protected] 27

Using Generic Classes and Automatic Boxing

April 05 Prof. Ismael H. F. Santos - [email protected] 28

Using Generic Classes and Automatic Boxing (Cont’d)

Program Output:

15

April 05 Prof. Ismael H. F. Santos - [email protected] 29

Collection Class Example

HashMap<Intger, Double> hm = new HashMap<Intger, Double> ();

// Note Auto-boxing from 15.hm.put (1,2.0);double coeff = hm.get(1);

Hashmap1.4 hm => Hashmap1.5<Object, Object>Hashmap1.4 hm => Hashmap1.5<Object, Object>

April 05 Prof. Ismael H. F. Santos - [email protected] 30

List Usage: Without Generics

List ys = new LinkedList();ys.add("zero");List yss;yss = new LinkedList();yss.add(ys);String y = (String)((List)yss.iterator().next()).iterator().next();

// EvilEvil runrun--time errortime errorInteger z = (Integer)ys.iterator().next();

16

April 05 Prof. Ismael H. F. Santos - [email protected] 31

List Usage: With Generics

List<String> ys = new LinkedList<String>();ys.add("zero");List<List<String>> yss;yss = new LinkedList<List<String>>();yss.add(ys);String y = yss.iterator().next().iterator().next();

// Compile-time error – much better!Integer z = ys.iterator().next();

April 05 Prof. Ismael H. F. Santos - [email protected] 32

List Implementation w/o Generics

class LinkedList implements List {protected class Node {

Object elt;Node next;Node(Object elt){elt = e; next = null;}

}protected Node h, t;public LinkedList() {h = new Node(null); t = h;}public void add(Object elt){

t.next = new Node(elt);t = t.next;

}}

Inner ClassRemember these?

Inner ClassRemember these?

17

April 05 Prof. Ismael H. F. Santos - [email protected] 33

List Implementation With Generics

class LinkedList<E >implements List<E>protected class Node {E elt;Node next;

Node(E elt){elt = e; next = null;} }protected Node h, t;public LinkedList() {h = new Node(null); t = h;}public void add(E elt){

t.next = new Node(elt);t = t.next;

}// …

}

April 05 Prof. Ismael H. F. Santos - [email protected] 34

Recall the Interator Interface

class LinkedList<E >implements List<E>// …

public Iterator<E> iterator(){return new Iterator<E>(){

protected Node p = h.next;public boolean hasNext(){return p !=

null;}public E next(){

E e = p.elt;p = p.next;return e;

}}

}}

Anonymous Inner Class(see Swing scribble

example)

Anonymous Inner Class(see Swing scribble

example)

18

April 05 Prof. Ismael H. F. Santos - [email protected] 35

A generic class definition can have any number of type parameters.

Multiple type parameters are listed in angular brackets just as in the single type parameter case, but are separated by commas.

Multiple Type Parameters

April 05 Prof. Ismael H. F. Santos - [email protected] 36

Multiple Type Parameters (Cont’d)

19

April 05 Prof. Ismael H. F. Santos - [email protected] 37

Multiple Type Parameters (Cont’d)

April 05 Prof. Ismael H. F. Santos - [email protected] 38

Using a Generic Class with Two Type Parameters

Program Output:

20

April 05 Prof. Ismael H. F. Santos - [email protected] 39

A Generic Classes and Exceptions

It is not permitted to create a generic class with Exception, Error, Throwable, or any descendent class of Throwable

A generic class cannot be created whose objects are throwable

public class GEx<T> extends Exception

The above example will generate a compiler error message

April 05 Prof. Ismael H. F. Santos - [email protected] 40

Methods Can Be Generic Also

interface Function<A,B>{ B value(A arg);}

interface Ntuple<T> {<S> Ntuple<S> map(Function<T,S> f);

}Ntuple<Integer> nti = ....;nti.map (new Function<Integer, Integer> {

Integer value(Integer i) {return new Integer(i.intValue()*2);

}}

);

21

April 05 Prof. Ismael H. F. Santos - [email protected] 41

Example: Generics and Inheritence

1st consider this code w/o Genericsclass ListUtilities {

public static Comparable max(List xs) {Iterator xi = xs.iterator();Comparable w = (Comparable) xi.next();while (xi.hasNext()) {

Comparable x = (Comparable) xi.next();if (w.compareTo(x) < 0) w = x;

}return w;

}} What dangers lurk here?What dangers lurk here?

April 05 Prof. Ismael H. F. Santos - [email protected] 42

Consider what happens (and when)

List xs = new LinkedList();xs.add(new Byte(0));Byte x = (Byte) ListUtilities.max(xs);List ys = new LinkedList();ys.add(new Boolean(false));

// EvilEvil runrun--time errortime errorBoolean y = (Boolean) ListUtilities.max(ys);

22

April 05 Prof. Ismael H. F. Santos - [email protected] 43

With Generics We Get Compile Check

List<Byte> xs = new LinkedList<Byte>();xs.add(new Byte(0));Byte x = ListUtilities.max(xs);List<Boolean> ys = new LinkedList<Boolean>();ys.add(new Boolean(false));

// Compile-time errorBoolean y = ListUtilities.max(ys);

April 05 Prof. Ismael H. F. Santos - [email protected] 44

Generics and Inheritance

Suppose you want to restrict the type parameter to express some restriction on the type parameter

This can be done with a notion of subtypes

Subtypes (weakly construed) can be expressed in Java using inheritance

So it’s a natural combination to combine inheritance with generics

23

April 05 Prof. Ismael H. F. Santos - [email protected] 45

Priority Queue Example

interface Comparable<I> { boolean lessThan(I); }

class PriorityQueue<T extends Comparable<T>> {T queue[ ] ; …void insert(T t) {

... if ( t.lessThan(queue[i]) ) ... }

T remove() { ... }...

}Said to be boundedSaid to be bounded

April 05 Prof. Ismael H. F. Santos - [email protected] 46

Bounded Parameterized Types

The <E extends Number> syntax means that the type parameter of MathBox must be a subclass of the Number class

We say that the type parameter is bounded

new MathBox<Integer>(5); //Legalnew MathBox<Double>(32.1); //Legalnew MathBox<String>(“No good!”);//Illegal

24

April 05 Prof. Ismael H. F. Santos - [email protected] 47

Bounded Parameterized Types

Inside a parameterized class, the type parameter serves as a valid type. So the following is valid.

public class OuterClass<T> {

private class InnerClass<E extends T> {…

}…

}

Syntax note: The <A extends B> syntax is valid even if B is an interface.

April 05 Prof. Ismael H. F. Santos - [email protected] 48

Bounded Parameterized Types

Java allows multiple inheritance in the form of implementing multiple interfaces, so multiple bounds may be necessary to specify a type parameter. The following syntax is used then:<T extends A & B & C & …>

Exampleinterface A {…}interface B {…}

class MultiBounds<T extends A & B> {…}

25

April 05 Prof. Ismael H. F. Santos - [email protected] 49

Using a Generic Class with Two Type Parameters

Program Output:

April 05 Prof. Ismael H. F. Santos - [email protected] 50

Bounds for Type Parameters

Sometimes it makes sense to restrict the possible types that can be plugged in for a type parameter T.

For instance, to ensure that only classes that implement the Comparable interface are plugged in for T, define a class as follows:

public class RClass<T extends Comparable>

"extends Comparable" serves as a bound on the type parameter T.

Any attempt to plug in a type for T which does not implement the Comparable interface will result in a compiler error message.

26

April 05 Prof. Ismael H. F. Santos - [email protected] 51

A bound on a type may be a class name (rather than an interface name)

Then only descendent classes of the bounding class may be plugged in for the type parameters:

public class ExClass<T extends Class1>

A bounds expression may contain multiple interfaces and up to one class.If there is more than one type parameter, the syntax is as follows:

public class Two<T1 extends Class1, T2 extends Class2 & Comparable>

Bounds for Type Parameters (Cont’d)

April 05 Prof. Ismael H. F. Santos - [email protected] 52

Bounds for Type Parameters (Cont’d)

27

April 05 Prof. Ismael H. F. Santos - [email protected] 53

Another example …

interface LessAndEqual<I> {boolean lessThan(I); boolean equal(I);

}class Relations<C extends LessAndEqual<C>> extends C {

boolean greaterThan(Relations<C> a) {return a.lessThan(this);

}boolean greaterEqual(Relations<C> a) {

return greaterThan(a) || equal(a);}boolean notEqual(Relations<C> a) { ... }boolean lessEqual(Relations<C> a) { ... }...

}

April 05 Prof. Ismael H. F. Santos - [email protected] 54

Generics and Subtyping

Is the following code snippet legal?List<String> ls = new ArrayList<String>(); //1List<Object> lo = ls; //2

Line 1 is certainly legal. What about line 2? Is a List of Strings a List of Object. Intuitive answer for most is “sure!”. But wait!The following code (if line 2 were allowed) would attempt to assign an Object to a String!

lo.add(new Object()); // 3String s = ls.get(0); // 4:

For all types P and C (i.e C is a subtype of P)Subtype(P,C) !=> Subtype(Generic<P>,Generic<C>)

For all types P and C (i.e C is a subtype of P)Subtype(P,C) !=> Subtype(Generic<P>,Generic<C>)

28

April 05 Prof. Ismael H. F. Santos - [email protected] 55

Subclassing a generic class

import java.awt.Color;

public class Subclass extends MyClass<Color> {

// You almost always need to supply a constructorpublic Subclass(Color color) {

super(color);}

public static void main(String[ ] args) {Subclass sc = new Subclass(Color.GREEN);sc.print(Color.WHITE);

} }

April 05 Prof. Ismael H. F. Santos - [email protected] 56

Generic Interfaces

An interface can have one or more type parameters.

The details and notation are the same as they are for classes with type parameters.

29

April 05 Prof. Ismael H. F. Santos - [email protected] 57

Generic Methods

When a generic class is defined, the type parameter can be used in the definitions of the methods for that generic class.

In addition, a generic method can be defined that has its own type parameter that is not the type parameter of any class

A generic method can be a member of an ordinary class or a member of a generic class that has some other type parameter.

The type parameter of a generic method is local to that method, not to the class.

April 05 Prof. Ismael H. F. Santos - [email protected] 58

The type parameter must be placed (in angular brackets) after all the modifiers, and before the returned type:

public static <T> T genMethod(T[] a)

When one of these generic methods is invoked, the method name is prefaced with the type to be plugged in, enclosed in angular brackets

String s = NonG.<String>genMethod(c);

Generic Methods (Cont’d)

30

April 05 Prof. Ismael H. F. Santos - [email protected] 59

Inheritance with Generic Classes

A generic class can be defined as a derived class of an ordinary class or of another generic class

As in ordinary classes, an object of the subclass type would also be of the superclass type

Given two classes: A and B, and given G: a generic class, there is no relationship between G<A> and G<B>

This is true regardless of the relationship between class Aand B, e.g., if class B is a subclass of class A

April 05 Prof. Ismael H. F. Santos - [email protected] 60

A Derived Generic Class: An Example

31

April 05 Prof. Ismael H. F. Santos - [email protected] 61

A Derived Generic Class: An Example (Cont’d)

Program Output:

April 05 Prof. Ismael H. F. Santos - [email protected] 62

Wildcards

Consider the problem of writing code that prints out all the elements in a collection before 1.5.

void printCollection(Collection c) { Iterator i = c.iterator();for (k = 0; k < c.size(); k++) { System.out.println(i.next());}

}

32

April 05 Prof. Ismael H. F. Santos - [email protected] 63

1st Naïve Try w/ Generics

void printCollection(Collection<Object> c) { for (Object e : c) {

System.out.println(e);}

}

The problem is that this new version is much less useful than the old one. The old code could be called with any kind of collection as a parameter, The new code only takes Collection<Object>, which, as is not a supertypeof all kinds of collections!

April 05 Prof. Ismael H. F. Santos - [email protected] 64

Correct way – Use Wildcards

So what is the supertype of all kinds of collections? Pronounced “collection of unknown” and denoted Collection<?>, A collection whose element type matches anything.It’s called a wildcard type for obvious reasons.

void printCollection(Collection<?> c) { for (Object e : c) {

System.out.println(e);}

}

33

April 05 Prof. Ismael H. F. Santos - [email protected] 65

Using Wildcards Again

public class Census { public static void addRegistry(Map<String, ? extends

Person> registry) { ...}}...

// Assuming Drivers are a subtype of PersonMap<String, Driver> allDrivers = ...;Census.addRegistry(allDrivers);

April 05 Prof. Ismael H. F. Santos - [email protected] 66

Implementing Generics

Type erasureCompile-time type checking uses genericsCompiler eliminates generics by erasing them

Compile List<T> to List, T to Object, insert casts

“Generics are not templates”Generic declarations are typecheckedGenerics are compiled once and for all

No instantiationNo “code bloat”

34

April 05 Prof. Ismael H. F. Santos - [email protected] 67

How Do Generics Affect My Code?

They don’t – except for the way you’ll code!Non-generic code can use generic libraries;For example, existing code will run unchanged with generic Collection library

April 05 Prof. Ismael H. F. Santos - [email protected] 68

ErasureErasure erases all generics type argument information at compilation phase.

E.g. List<String> is converted to ListE.g. String t = stringlist.iterator().next() is converted to String t = (String) stringlist.iterator().next()

As part of its translation, a compiler will map every parameterized type to its type erasure.

35

April 05 Prof. Ismael H. F. Santos - [email protected] 69

Erasure

List <String> l1 = new ArrayList<String>();List<Integer> l2 = new ArrayList<Integer>();System.out.println(l1.getClass() == l2.getClass());