Professional Documents
Culture Documents
Advanced Java Programming: Maurizio Cimadamore Mcimadamore@deis - Unibo.it
Advanced Java Programming: Maurizio Cimadamore Mcimadamore@deis - Unibo.it
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Outline
1
Inner Classes
Member Inner Classes
Local Inner Classes
Anonymous Inner Classes
Static Inner Classes
Inner Classes Implementation
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Inner Classes
Introduction
JDK 1.1 introduced the key-concept of inner class
An inner class is a class whose declaration appear within:
class declarations
method bodies
expressions
The aim is in enforcing the encapsulation providing a clean
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Basic Definitions
The Scope of a class
A class is associated to an enclosing scope which can be
a package if the class is a toplevel class
a class/method declaration if the class is an inner class
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Properties
A MI always have an enclosing instance which:
must be specified when creating a new instance of a MI
fs.new FixedStackEnum(); //fs is a FixedStack
can be accessed within a MI through the this keyword
FixedStack.this //within FixedStackEnum
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
A read-only class
public class FixedStack {
class FixedStackEnum implements Enumeration {
private FixedStackEnum() {...} //cannot access it from outside
}
...
}
...
FixedStack fs = new FixedStack(10);
FixedStack.FixedStackEnum it1 = fs.new FixedStackEnum();//error!
FixedStack.FixedStackEnum it1 = fs.getEnumeration();//ok!
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Private MIs
Private MI
What if a read-only class is itself declared as private?
Access forbidden (not only instantiation) from outside. . .
. . . the MI can thus be used only by its enclosing class
A read-only class
public class FixedStack {
/* cannot access it from outside */
private class FixedStackEnum implements Enumeration {
FixedStackEnum() {...} //cannot access it from outside
}
...
}
...
FixedStack fs = new FixedStack(10);
FixedStack.FixedStackEnum it1 = fs.new FixedStackEnum();//error!
FixedStack.FixedStackEnum it1 = fs.getEnumeration();//error!
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
which it is used
Declaring classes to be used only locally (within the block
Properties
LI have the same visibility as variables in blocks
LI may access any name available in ordinary expressions
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Properties
An AI is always a subtype of some type specified in the new
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Graph();
= new Graph.Node(10,20); //full qualified name needed
= new Graph.Node(20,10); //full qualified name needed
= new Graph.Arc(n1, n2); //full qualified name needed
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Properties
A SI is equivalent to a toplevel class (its enclosing scope is
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Brief Summary
Declaring an inner class
MI and SI appear within the body of a class
LI and AI appear within the body of a method
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Some complications. . .
Must be taken into account that an inner class may access:
one of its enclosing instances (MI, LI, AI)
a final variable of its declaring scope (LI, AI);
a field (even private ones) of its enclosing class(es)
Some of the above aspect are quite not obvious (given two
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
class FixedStack$FixedStackEnum
This way translated inner classes can still access fields of their
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Properties
WorkerThread is visible to any class . . .
. . . is there any way to make WorkerThread only available
within WorkerThread?
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Properties
WorkerThread is only available within WorkerThread. . .
. . . what if we want WorkerThread to be accessed only within
startWork ?
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Properties
WorkerThread is only available within startWork
Its used only once. . . any idea?
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Properties
WorkerThread no longer exists. . .
. . . Its definition has been inlined directly into startWork to
Inner Classes
Generics
Generics in JDK5.0
Outline
1
Inner Classes
Generics
Why Java Generics?
Generic Classes/Methods
Subtyping vs. Generics
Wildcards
Generics in JDK5.0
Runtime Generics
Conclusions
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Numbers
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
History
the GJ (Generic Java) project, started in 1996, aimed to bring
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Properties
List<E> is a generic class declaring a type variable E
E is a placeholder for concrete Java types
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Properties
When creating an instance of List<E> a concrete
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Properties
<Z>reverseList is a generic method declaring a type
variable Z
Z can only be referenced within the body of reverseList
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Properties
When invoking <Z>reverseList a concrete instantiation
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Generic Quiz
A generic Cell
class Cell<E extends Number> {
E e;
public Cell(E e) {this.e = e;}
public static <K> Cell<K> makeCell(K k) {
return new Cell<K>(k);
}
}
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Generic Quiz
A generic Cell
class Cell<E extends Number> {
E e;
public Cell(E e) {this.e = e;}
public static <K> makeCell(K k) {
return new Cell<K>(k);
}
}
Solutions
Cell can only be instantiated to any Cell<T>, T <: Number
This program wont compile because of the type variable K in
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Java Arrays
Subtyping beetween Java arrays
There is a similarity beetween Java arrays and generic types. . .
. . . Pet[], Kitten[] can be thought of as Array<Pet>,
Array<Kitten>
if S is a subtype of T (S <: T) then S[] <: T[] as well
This is called covariance
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
runtime check
This means that when an element is assigned to an array it is
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
general functions
Covariance could be useful in factorizing generic types
List<Kitten> <: List<Pet> since Kitten <: Pet!
A different approach
Instead of enforcing direct subtyping we could introduce new
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
List<Kitten> lk = ...
List<Doggy> ld = ...
List<Integer> li = ...
Pets.petGreetings(lk); //ok!
Pets.petGreetings(ld); //ok!
Pets.petGreetings(li); //NO!
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
List<Object> lo = ...
List<Pet> lp = ...
List<Kitten> lk = ...
Pets.replaceWithDogs(lo); //ok!
Pets.replaceWithDogs(lp); //ok!
Pets.replaceWithDogs(lk); //NO!
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Bivariant Types
Syntax and use of bivariant types
List<?> is a bivariant type which is supertype of all List<S>
for every S.
List<Object>, List<Pet>, List<Doggy> <: List<?>
An element of type List<Object>, List<Pet>, List<Doggy>
List<Kitten> lk = ...
List<Doggy> ld = ...
List<Integer> li = ...
Pets.countPets(lk); //ok!
Pets.countPets(ld); //ok!
Pets.countPets(li); //ok!
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Wildcards as Intervals
An useful metaphore
You can think of a wildcard C<? [(extends|super) T]> as
=
=
=
=
[Pet,nulltype]
[Object,Pet]
[Object,nulltype]
[Doggy,Doggy]
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Drawing Wildcards
List<?>
List<Doggy>
Object
Pet
Doggy
nulltype
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
containment test
Given a generic type T and a wildcard W,if Ws interval
contains T then T <: W
List<Doggy> <: List<?>
List<Doggy> <: List<? extends Pet>
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Subtyping at a Glance
List<?>
List<Doggy>
Object
Pet
Doggy
nulltype
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Wildcards Quiz
1
List<?>
Object
Number
nulltype
2
List<? extends Number>
Object
Number
nulltype
3
List<? super Number>
Object
Number
nulltype
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Object
Number
nulltype
2
List<? extends Number>
Object
Number
nulltype
3
List<? super Number>
Object
Number
nulltype
Inner Classes
Generics
Generics in JDK5.0
Outline
1
Inner Classes
Generics
Generics in JDK5.0
Java Collection Framework
Remarkable Generic Interfaces
Java Reflection API
Runtime Generics
Conclusions
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
and wildcards
Samples
Java Collection Framework
core Java interfaces (e.g. Comparable)
Java Reflection API
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
collection class
Every collection class must implements the iterator method
This method returns an Iterator object whose methods can
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Iterator<E> iterator()
The JDK5.0s Iterator class
interface Iterator<E> {
boolean hasNext()
E next()
void remove()
}
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Iterating a Collection
For iterating all elements of a given collection c you can use
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
specified in Expression
each round assigning an element to the variable in VarDecl
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
interface
Comparable<E> is a one-method interface defining the
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Comparing Pets
Another Pet class
abstract class Pet implements Comparable<Pet> {
String name;
Pet(String name) {
this.name = name;
}
public int compareTo(Pet pet) {
return name.compareTo(pet.name);
}
abstract void sayHello();
}
Sorting Pets
ArrayList<Doggy> ald = new ArrayList<Doggy>();
ald.add(new Doggy("3:Snoopy"));
ald.add(new Doggy("1:Pippo"));
ald.add(new Doggy("2:Pluto"));
java.util.Collections.sort(ald);
System.out.println(ald);
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
java.util.Collection<E>
boolean addAll(Collection<? extends E> c)
boolean removeAll(Collection<?> c)
boolean retainAll(Collection<?> c)
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Outline
1
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Compile time vs. Runtime Approach
Type Erasure in JDK5.0
Generic Types at Runtime
A Case Study: Generic Arrays
Conclusions
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Runtime approach
Direct support for generics into the JVM affects:
core classes (e.g. ClassLoader)
classfile format
JVMs runtime type system
Generic code only runs on generic JVMs
Better performances but compatibility issues!
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Erasing Lists
Generic List
class List<E> {
E head;
List<E> tail;
List(E head, List<E> tail) {
this.head = head;
this.tail = tail;
}
List<E> append(E el) {
return nonEmpty()
? new List<E>(head, tail.append(el))
: new List<E>(el,new EmptyList<E>());
}
public boolean nonEmpty() {
return true;
}
}
class EmptyList<E> extends List<E> {
EmptyList() {super(null,null);}
public boolean nonEmpty() {return false;}
}
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Erasing Lists
Generic List translated
class List {
Object head;
List tail;
List(Object head, List tail) {
this.head = head;
this.tail = tail;
}
List append(Object el) {
return nonEmpty()
? new List(head, tail.append(el))
: new List(el,new EmptyList());
}
public boolean nonEmpty() {
return true;
}
}
class EmptyList extends List {
EmptyList() {super(null,null);}
public boolean nonEmpty() {return false;}
}
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Runtime Generics
generic/wildcard types
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
A Possible Workaround
Another generic FixedStack
public class FixedStack<E> {
Object[] array;
int top = 0;
FixedStack(int fixedSizeLimit) {
array = new Object[fixedSizeLimit]; //ok!
}
public void push(E item) {
array[top == array.length ? top - 1 : top++] = item;
}
public E pop() {
return (E)array[top == 0 ? top : top--]; //unchecked warning!
}
...
}
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Another Workaround
Yet another generic FixedStack
public class FixedStack<E> {
E[] array;
int top = 0;
FixedStack(int fixedSizeLimit) {
array = (E[])new Object[fixedSizeLimit]; //unchecked warning!
}
public void push(E item) {
array[top == array.length ? top - 1 : top++] = item;
}
public E pop() {
return array[top == 0 ? top : top--]; //ok!
}
...
}
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
unchecked warning!
Is this a problem?
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Outline
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Any Question?
Runtime Generics
Conclusions
Inner Classes
Generics
Generics in JDK5.0
Runtime Generics
Conclusions