Professional Documents
Culture Documents
Advanced Java Programming: Maurizio Cimadamore Mcimadamore@deis - Unibo.it
Advanced Java Programming: Maurizio Cimadamore Mcimadamore@deis - Unibo.it
Maurizio Cimadamore
mcimadamore@deis.unibo.it
DEIS
Alma Mater Studiorum—Università di Bologna
1 Inner Classes
2 Generics
3 Generics in JDK5.0
4 Runtime Generics
5 Conclusions
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
Outline
1 Inner Classes
Member Inner Classes
Local Inner Classes
Anonymous Inner Classes
Static Inner Classes
Inner Classes Implementation
2 Generics
3 Generics in JDK5.0
4 Runtime Generics
5 Conclusions
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
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
way for structuring classes within a package. . .
• . . . we’ll see what it means in a moment!
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
Basic Definitions
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
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
Read-only classes
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!
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
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!
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
Properties
AI sample
public class FixedStack {
Properties
AI in method calls
• There are situations in which we define a class only for
overriding a few methods of its superclass/superinterface
AI and Swing
public class GUI extends JFrame {
public GUI(final String msg) {
Button b;
add(b = new Button("Click Here!"));
b.setActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(GUI.this,"Hello! "+msg);
}
});
pack(); setVisible(true);
}
}
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
AI in method calls
• This tend to happen very frequently using Swing since we
have to define custom Listener classes for handling events
AI and Swing
public class GUI extends JFrame {
public GUI(final String msg) {
Button b;
add(b = new Button("Click Here!"));
b.setActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(GUI.this,"Hello! "+msg);
}
});
pack(); setVisible(true);
}
}
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
Useful for...
• Modeling tightly coupled entities (a Graph is made up of
some Nodes and some Arcs)
• Providing meaningful namespaces (Graph.Node vs. Node)
Properties
Brief Summary
Declaring an inner class
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
classes A and B, how can A refer to a B’s private field?)
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
FixedStack translated
public class FixedStack {
Object array[];
int top = 0;
FixedStack$FixedStackEnum(FixedStack this$0) {
this.this$0 = this$0;
int count = this$0.top; //outer field access!
}
Properties
Properties
HelloWorker (3)
public class HelloWorker {
public void startWork() {
class WorkerThread implements Runnable {
public void run() {
System.out.println("Hello World!");
}
};
new WorkerThread().run();
}
}
Properties
Properties
Outline
1 Inner Classes
2 Generics
Why Java Generics?
Generic Classes/Methods
Subtyping vs. Generics
Wildcards
3 Generics in JDK5.0
4 Runtime Generics
5 Conclusions
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
...
Vector numbers;
numbers = new Vector();
numbers.add(new Integer(4));
...
numbers.add("One"); //OK for javac!
...
int[] intArr = toIntArray(numbers);
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
...
Vector<Number> numbers;
numbers = new Vector<Number>();
numbers.add(new Integer(4));
...
numbers.add("One"); //won’t compile!
...
int[] intArr = toIntArray(numbers);
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
History
Properties
Properties
Properties
Properties
• There are cases which don’t fit well with the inference scheme
• Often is better specifying method type parameters explicitly
(rather than relying on type inference)
Bounded polymorphism
• Instantiation of method/class type variable T can be
constrained by stating that T must:
• extend a given class (through extends)
• implement a given set of interfaces (through &)
• If no bound is specified, T extends Object is assumed
Generic Quiz
A generic Cell
class Cell<E extends Number> {
E e;
Generic Quiz
A generic Cell
class Cell<E extends Number> {
E e;
Solutions
• Cell can only be instantiated to any Cell<T>, T <: Number
• This program won’t compile because of the type variable K in
makeCell. . . do you see why?
• Clue: it has to do with bounded polymorphism. . .
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
Java Arrays
A different approach
...
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
...
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
...
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
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>
can be passed where a List<?> is expected
• Useful for defining functionalities which do not read nor write
Wildcards as Intervals
An useful metaphore
Drawing Wildcards
List<?>
List<Doggy>
Subtyping at a Glance
List<?>
List<Doggy>
Wildcards Quiz
1
List<?>
2
List<? extends Number>
3
List<? super Number>
2
List<? extends Number>
3
List<? super Number>
Outline
1 Inner Classes
2 Generics
3 Generics in JDK5.0
Java Collection Framework
Remarkable Generic Interfaces
Java Reflection API
4 Runtime Generics
5 Conclusions
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
Samples
Obtaining an Iterator
Iterating a Collection
• For iterating all elements of a given collection c you can use
the following pattern
1. retrieve an Iterator object i through c.iterator()
2. if i.hasNext() = false we’re done; otherwise. . .
3. retrieve next c’s element through i.next()
4. repeat from step 2
• Or you can let Java do the task for you!
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
Comparing Objects
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);
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
<T> void copy(List<? super T> dest, List<? extends T> src)
java.util.Collection<E>
boolean addAll(Collection<? extends E> c)
boolean removeAll(Collection<?> c)
boolean retainAll(Collection<?> c)
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
Outline
1 Inner Classes
2 Generics
3 Generics in JDK5.0
4 Runtime Generics
Compile time vs. Runtime Approach
Type Erasure in JDK5.0
Generic Types at Runtime
A Case Study: Generic Arrays
5 Conclusions
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
Runtime approach
• Direct support for generics into the JVM affects:
• core classes (e.g. ClassLoader)
• classfile format
• JVM’s runtime type system
• Generic code only runs on generic JVMs
• Better performances but compatibility issues!
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
Erasing Lists
Generic List
class List<E> {
E head;
List<E> tail;
Erasing Lists
Generic List translated
class List {
Object head;
List tail;
Runtime Generics
Unckecked warnings
E[] array;
int top = 0;
FixedStack(int fixedSizeLimit) {
array = new E[fixedSizeLimit]; //won’t compile!
}
public E pop() {
return array[top == 0 ? top : top--];
}
...
}
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
A Possible Workaround
Object[] array;
int top = 0;
FixedStack(int fixedSizeLimit) {
array = new Object[fixedSizeLimit]; //ok!
}
public E pop() {
return (E)array[top == 0 ? top : top--]; //unchecked warning!
}
...
}
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
Another Workaround
E[] array;
int top = 0;
FixedStack(int fixedSizeLimit) {
array = (E[])new Object[fixedSizeLimit]; //unchecked warning!
}
public E pop() {
return array[top == 0 ? top : top--]; //ok!
}
...
}
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
An UnsafeVector
class UnsafeVector<E> extends java.util.Vector<E> {
Outline
1 Inner Classes
2 Generics
3 Generics in JDK5.0
4 Runtime Generics
5 Conclusions
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
class PermutationUtility{
private static String theory =
"remove([X|Xs],X,Xs). \n" +
"remove([X|Xs],E,[X|Ys]):-remove(Xs,E,Ys). \n" +
"permutation([],[]). \n" +
"permutation(Xs,[X|Ys]):-remove(Xs,X,Zs),permutation(Zs,Ys).";
Any Question?
Inner Classes Generics Generics in JDK5.0 Runtime Generics Conclusions
Maurizio Cimadamore
mcimadamore@deis.unibo.it
DEIS
Alma Mater Studiorum—Università di Bologna