Download Slides on Java Generics - Organization of Programming Languages | CMSC 330 and more Study notes Programming Languages in PDF only on Docsity!
CMSC 330: Organization of
Programming Languages
Java Generics
An Integer Stack Implementation
class Stack { class Entry { Integer elt; Entry next; Entry(Integer i, Entry n) { elt = i; next = n; } } Entry theStack; void push(Integer i) { theStack = new Entry(i, theStack); } Integer pop() throws EmptyStackException { if (theStack == null) throw new EmptyStackException(); else { Integer i = theStack.elt; theStack = theStack.next; return i; }}}
Polymorphism Using Object
class Stack { class Entry { Object elt; Entry next; Entry(Object i, Entry n) { elt = i; next = n; } } Entry theStack; void push(Object i) { theStack = new Entry(i, theStack); } Object pop() throws EmptyStackException { if (theStack == null) throw new EmptyStackException(); else { Object i = theStack.elt; theStack = theStack.next; return i; }}}
New Stack Client
Stack is = new Stack(); Integer i; is.push(new Integer(3)); is.push(new Integer(4)); i = (Integer) is.pop();
• Now Stacks are reusable
- (^) push() works the same
- (^) But now pop() returns an Object
- (^) Have to downcast back to Integer
- (^) Not checked until run-time
Parametric Polymorphism (for Classes)
• After Java 1.5 we can parameterize the Stack
class by its element type
• Syntax:
- (^) Class declaration: class A { ... }
- (^) A is the class name, as before
- (^) T is a type variable , can be used in body of class (...)
- (^) Client usage declaration:A x;
- (^) We instantiate A with the Integer type
class Stack { class Entry { ElementType elt; Entry next; Entry(ElementType i, Entry n) { elt = i; next = n; } } Entry theStack; void push(ElementType i) { theStack = new Entry(i, theStack); } ElementType pop() throws EmptyStackException { if (theStack == null) throw new EmptyStackException(); else { ElementType i = theStack.elt; theStack = theStack.next; return i; }}}
Parametric Polymorphism for Stack
Parametric Polymorphism for Methods
- (^) String is a subtype of Object
- (^) static Object id(Object x) { return x; }
- (^) static Object id(String x) { return x; }
- (^) static String id(Object x) { return x; }
- (^) static String id(String x) { return x; }
- (^) Can’t pass an Object to 2 or 4
- (^) 3 doesn’t type check
- (^) Can pass a String to 1 but you get an Object back
Parametric Polymorphism, Again
• But id() doesn’t care about the type of x
- (^) It works for any type
• So parameterize the static method :
static T id(T x) { return x; } Integer i = id(new Integer(3));
- (^) Notice no need to instantiate id; compiler figures out the correct type at usage
- (^) The formal parameter has type T, the actual parameter has type Integer
Translation via Erasure
• Replace uses of type variables with Object
- (^) class A { ...T x;... } becomes
- (^) class A { ...Object x;... }
• Add downcasts wherever necessary
- (^) Integer x = A.get(); becomes
- (^) Integer x = (Integer) (A.get());
• So why did we bother with generics if they’re
just going to be removed?
- (^) Because the compiler still did type checking for us
- (^) We know that those casts will not fail at run time
Limitations of Translation
• Some type information not available at compile-
time
- (^) Recall type variables T are rewritten to Object
• Disallowed, assuming T is type variable:
- (^) new T() would translate to new Object() (error)
- (^) new T[n] would translate to new Object[n] (warning)
- (^) Some casts/instanceofs that use T
- (^) (Only ones the compiler can figure out are allowed)
Polymorphism Quiz
• What kind of polymorphism?
- Possible answers: subtype, parametric (classes or methods), or ad-hoc
• foo(x) takes floats and ints because the
programmer provided two different versions of
the function, one for each type
int foo(int x) { return x+1; } float foo(float x) { return x+1.0; }
Polymorphism Quiz
• What kind of polymorphism?
- Possible answers: subtype, parametric (classes or methods), or ad-hoc
• foo(x) takes Floats and Integers because both
are subclasses of Numbers
class Number { } class Float extends Number { } class Integer extends Number { } String foo(Number x) { return x.toString(); }
Polymorphism Quiz
• What kind of polymorphism?
- Possible answers: subtype, parametric (classes or methods), or ad-hoc
• foo(x) takes Floats and Integers because the
programmer used generics
T foo(T x) { return x; }
Polymorphism Quiz
• What kind of polymorphism?
- Possible answers: subtype, parametric (classes or methods), or ad-hoc
• the constructor for class Foo takes Floats and
Integers because the programmer used generics
class Foo { Foo(T x) { } }