23
1 Generics in Java and Beyond Martin Buechi © 2001 by Martin Büchi

Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

1

Generics in Java and Beyond

Martin Buechi

© 2001 by Martin Büchi

Page 2: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

2

Overview

Generics• Abstraction of generic concepts.

• C++ templates (STL), parameterized types, ML polymorphic datatypes and functions, Beta virtual types

• First usage: CLU 1977

Talk overview• Introduction to generic programming• Implementation techniques for generics• Generics in JDK 1.5 (2003)

Page 3: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

3

Stack: Generic Pattern & Generics

class Stack {void push(Object o) {…}

Object pop() {…}…

}

// stack of String

Stack s = new Stack();st.push(“Hello”);…

…s = (String)st.pop();

unnecessary cast

st.push(new Object()); // ok

run-time exception

class Stack<A> {void push(A o) {…}

A pop() {…}…

}

// stack of String

Stack<String> s = new Stack<String>();st.push(“Hello”);…

…s = st.pop(); // no cast needed

st.push(new Object()); // compile-time error

public Stack(Class t) {this.t = t;}

private Class t;

if(t.isInstanceOf(o))

exception

Page 4: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

4

Bounded Polymorphism

interface Priority {int getPriority();

}class A implements Priority {

public int getPriority() {…}

}class PriorityQueue<E > {

E queue[];

void insert(E e) {…if(e.getPriority() < queue[i].getPriority()) {…}

…}

}

PriorityQueue<A> p = new PriorityQueue<A>();p.insert(new A());

implements Priority

Page 5: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

5

F-Bounded Polymorphism

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

}class A implements Comparable<A> {

public boolean lessThan(A o) {…}

}class SortedList<E implements Comparable<E>> {

E list[];

void insert(E e) {…if(e.lessThan(list[i])) {…}

…}

}

Page 6: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

6

Mix-Ins

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

boolean equal(I o);}class A implements LessAndEqual {…}

class Relations<C implements LessAndEqual<C>> extends C {boolean lessThanEqual(Relations<C> a) {

return lessThan(a) || equal(a);

}}

Relations<A> x = new Relations<A>();Relations<A> y = new Relations<A>();if(x.lessThanEqual(y)) {…}

Page 7: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

7

Parameterized Methods

public final class Std { public static <T implements Comparable> T min(T a, T b) {

if(a.compareTo(b) <= 0) return a; else return b; }

}

public class Main {

public static void main(String[] args) { Integer b1 = new Integer(2); Integer b2 = new Integer(5); Integer bMin = Std.min(b1, b2);

Date d1 = new Date(101, 05, 10); Date d2 = new Date(101, 03, 8); Date dMin = Std.min(d1, d2); System.out.println("The minimums are: " + bMin + " and " + dMin);

}}

Page 8: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

8

Bounds: Name vs Structural Subtyping

class PriorityQueue<E implements Priority> {… e.getPriority() …}

class A implements Priority {int getPriority() {…}

}

class B {int getPriority() {…}

}

//okPriorityQueue<A> p = new PriorityQueue<A>();

// compile-time error with name equivalence, ok with structural equivalencePriorityQueue<B> p = new PriorityQueue<B>();

class PriorityQueue<E where {int getPriority();}> {…}

Page 9: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

9

Insufficient Bounds: Duplicates/Overriding

Duplicate methodsclass C<A implements I> {

int m(A s) {return 1;}int m(String s) {return 2;}

}

• Instantiation C<String> illegal: two methods m(String).

Overriding errorclass C<A implements I> extends A {

int m() {return 1;}

}class X implements I {

void m() {…}

}• Instantiation C<X> illegal: int m() cannot override void m().• Negative type information would be a solution

Page 10: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

10

Insufficient Bounds: Instance Creation

class C<A implements I> {void f() {

A a = new A();}

}

Actual parameter must be a concrete class• abstract class X implements I {…} C<X> x = new C<X>()

Actual parameter must have an accessible defaultconstructor• class Y implements I {Y(int i) {};} C<Y> y = new C<Y>()

Bound is insufficient• Instantiation that satisfies bound visible from interface may be illegal.

Page 11: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

11

Subtyping

Subtyping of parameterized class impliessubtypingclass Collection<A> {…}

class Set<A> extends Collection<A> {…}Collection<X> x = new Set<X>

Instantion with subtype does not imply subtypingclass Collection<A> {…}class Y extends X {…}Collection<Y> y = new Collection<Y>;

Collection<X> x = y; // compile-time errorx.insert(new X()); // would violate soundness

Y[] y = new Y[10];

X[] x = y; // legalx[0] = new X(); //ArrayStoreExc.

Page 12: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

12

Implementation: Textual Substitution

Generic declaration treated as textual macro• Source code necessary for instantiation

Big and fast• Every instantiation consumes secondary & primary storage• Speed optimization possible at compile time (limited usefulness)

Full reflective inquiry supportPackage-based accessibility too restrictive• Instantiation of generic class p.x accessing package-protected class p.y

with package-protected class q.z is not possible

Runs on current JVM• Reflection does not reveal genericity (Generic class, instantiation

parameters(s))

C++ templates based on textual substitution

Page 13: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

13

Implementation: Heterogeneous Translation

Generic class compiled into extended class file• Compilation of generic class produces generic class file

• Normal class file generated upon instantiation

Rest as textual substitution

Page 14: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

14

Implementation: Load-Time Instantiation

Compilation of generic class into class file withextensions for compiler and loader• Class loader creates instantiations

• Change of class loader required, but not of verifier/interpreter (security)

Small in secondary, big at run-time, pretty fast• Only one class file in secondary storage, fast to transmit (applets)

• Run-time memory needed for each instantiation• Run-time (loader, JIT, adaptive) speed optimizations possible

Full reflectionPackage-based accessibility too restrictive• Generic class p.x accessing package-protected class p.y instantiated with

package-protected class q.z is not possible

Minimal changes to JVM required

Page 15: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

15

Implementation: Generic JVM

Compilation of generic class into class file withextensions for compiler and JVM• JVM loads, verifies, and executes generic class file

• Change of JVM, including verifier/interpreter (security)

Small in secondary, small at run-time, pretty fast• Only one class file in secondary storage, fast to transmit (applets)

• JVM can optimize run-time memory vs. speed

Full reflectionBig change to JVM required

Page 16: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

16

Implementation: Homogeneous Translation

Compilation of generic class into class file withextensions for compiler only• Formal type parameters replaced by bound

• Loss of type safety at run time (e.g., can push Object on stack of Strings)

Small and slow• Only one class file in secondary storage, fast to transmit (applets)

• Only one instance at run time• No speed optimizations possible (small problem for reference types)• Speed penalty due to casts

Limited reflectionRuns on current JVM

Page 17: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

17

Generics in Java

Last minute consideration by Gosling and Joy• Scrapped due to time pressure, immature proposal, complexity

Several proposals to add (ECOOP, OOPSLA)Java Community Process• JSR14• Most wanted language feature in Bug Parade

Most likely in JDK 1.5 in 2003Based on GJ• Published in OOPSLA 1998• Basis for javac in JDK 1.3

• GJ contains generic version of Collection API• Binary freely available for download

Page 18: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

18

GJ: Overview

F-bounded polymorphismNo mix-ins (parameter as superclass)No change of the virtual machineHomogeneous translationLittle support for reflectionNo instantiation with primitive typesNo non-type parameters (functors, constants, …)Solves the generic legacy problem

Page 19: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

19

GJ: Old Code and New Generic Libraries

Compilation: replacement of parameter by bound// GJ source

class PQ<E implements Priority> {E queue[];E removeFirst() {…}

}PQ<A> p = new PQ<A>();p.insert(new A());

A a = p.removeFirst();

Combination with old code• For JVM, generic code is like code adhering to generic pattern

– Code compiled for non-generic version of Collection API works withcompilation of generic API

Compilation of new generic instantiations• Class file extension contains bound and parameter

// Equivalent byte-code for JVM

class PQ {Priority queue[];Priority removeFirst() {…}

}PQ p = new PQ();p.insert(new A())

A a = (A)p.removeFirst();

Page 20: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

20

GJ: Retrofitting Old Code

Retrofitting of non-generic binary code// Non-generic class

// only binary available// PriorityQueue.classclass PriorityQueue {

Priority queue[];Priority removeFirst() {…}

}

gjc PriorityQueue.java -retro PathOfClassFile• Adds generic type information from PriorityQueue.java to

PriorityQueue.class.• Does not change byte code used by JVM, only adds information for

correct compilation of instantiations of generic class.

Current GJ comes with retrofitted Collection API

// Typing information for retrofitting

// No/dummy implementation// PriorityQueue.javaclass PriorityQueue<E implements Priority> {

E queue[];E removeFirst() {return null;}

}

Page 21: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

21

Try It!

JDK 1.5 now: GJ• http://www.cs.bell-labs.com/~wadler/pizza/gj/

C++ templates (STL)• Unbounded

For the brave: gbeta• Generics in form of virtual types.

• Run-time instantiation of generics• http://www.daimi.aau.dk/~eernst/gbeta/

Page 22: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

22

Read More!

Genericity in Java• Java Specification Request 14:

http://java.sun.com/aboutJava/communityprocess/

• Bank, Liskov, and Myers. Parameterized Types and Java. POPL ‘97.• Thorup. Genericity in Java with Virtual Types. ECOOP ‘97.• Agesen, Freund, and Mitchell. Adding Type Parameterization to the

Java Language. OOPSLA 97.

• Bracha, Odersky, Stoutamire, and Wadler. Making the future safe forthe past: Adding Genericity to the Java Programming Language.OOPSLA ‘98.

• Cartwright and Steele. Compatible Genericity with Run-time Typesfor the Java Programming Language. OOPSLA ‘98.

Type theory• Fisher and Mitchell. The Development of Type Systems for Object-

Oriented Languages. Theory and Practice of Object Systems, 1(3):189–220.

Page 23: Generics in Java and Beyondjava.ociweb.com/javasig/knowledgebase/2001May/JavaGenerics.pdfspeed, safety, reflection accuracy, and need for changes to the JVM. Q Generics in Java •

23

Summary & Conclusions

Generics are useful• Reuse through instantiation of generic concept

• More compile-time error checking and fewer run-time exceptions• Fewer casts: easier to write and faster to execute

Implementations• Different tradeoffs with respect to secondary and primary memory,

speed, safety, reflection accuracy, and need for changes to the JVM.

Generics in Java• Official support in JDK 1.5, scheduled for 2003• GJ available now, generated code interoperable with normal Java