24
Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Embed Size (px)

DESCRIPTION

Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005. Motivation. In 1998, Java represented a quantum leap forward in mainstream programming technology. How could the PL community make it better? - PowerPoint PPT Presentation

Citation preview

Page 1: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Java Generics

Robert “Corky” Cartwright Rice University

19 Jan 2005

Page 2: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Motivation

In 1998, Java represented a quantum leap forward in mainstream programming technology. How could the PL community make it better?

Enriching the data model and associated type system. “Adding genericity” in the terminology of OO language designers.

Page 3: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Rules of the Game for Extending Rules of the Game for Extending JavaJava

• Upward compatibility: old program binaries Upward compatibility: old program binaries behave as before (excluding programs that behave as before (excluding programs that make extensive use of reflection)make extensive use of reflection)

• No changes to the JVM (except libraries)No changes to the JVM (except libraries)

• Interoperability between old and new codeInteroperability between old and new code

• Extension through revised compiler (javac) Extension through revised compiler (javac) and class loaderand class loader

• Coherence with the existing language Coherence with the existing language designdesign

Page 4: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Potential changesPotential changes

• Moving primitive types into the object type hierarchy (not done correctly in C#).

• Parametric polymorphism for classes, interfaces, and methods.

• Full “first class” genericity: allow type variables as superclasses supporting abstraction with respect to the superclass of a class definition (OO mixins).

Page 5: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Blueprint for Extending Java• Design a coherent extension of existing language.

• Implement the extension without changing the JVM including run-time libraries (except additions).

• Extensions must be supported entirely by the source language compiler (javac) and extensions to class loader.

• Ensure that the overhead should be low.

• Key tricks: – A source program may generate extra class files (Precedent: inner

classes).

– Class files may be augmented by new attributes.

Page 6: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Adding Genericity (Parametric Adding Genericity (Parametric Polymorphism)Polymorphism)

• What is parametric polymorphism?What is parametric polymorphism?The parameterization of types, The parameterization of types, e.g.,e.g., adding a adding a parameter to the parameter to the ListList type so that type so that List<Integer>List<Integer> designates a list containing only integers.designates a list containing only integers.

• In Java, coherence is a challenging problem:In Java, coherence is a challenging problem:– Array types are already generic with Array types are already generic with co-variant co-variant

subtypingsubtyping ( (Integer[]Integer[] is a subtype of is a subtype of Number[]Number[]).).

– Co-variant subtyping conflicts with flexible static Co-variant subtyping conflicts with flexible static type checking (updates are type checking (updates are contra-variantcontra-variant).).

– Supporting generic run-time types requires Supporting generic run-time types requires significant new execution machinery.significant new execution machinery.

• Container classes should easily migrate to Container classes should easily migrate to corresponding generic classes, corresponding generic classes, e.g.e.g.

VectorVector Vector<T>Vector<T>

Page 7: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Generics in Java 1.5 (Generics in Java 1.5 (Odersky, Wadler, et Odersky, Wadler, et

alal))• Any class or method can be parameterized by type, which Any class or method can be parameterized by type, which

introduces type variables just as introduces type variables just as introduces data variables in introduces data variables in Scheme.Scheme.

Class C<T> { … /* T can be used almost anywhere an ordinary type is used */ }Class C<T> { … /* T can be used almost anywhere an ordinary type is used */ } Class D { Class D { <T> T first(List<T>) { /* The scope of T is the method definition */ …} <T> T first(List<T>) { /* The scope of T is the method definition */ …} … … } }

• Each type parameter has an upper bound (Each type parameter has an upper bound (ObjectObject by default) by default) specified by an specified by an extendsextends clause, clause, e.g.e.g., , class E<T extends Number> { … }class E<T extends Number> { … }

• Type parameters are Type parameters are non-variantlynon-variantly subtyped, subtyped, e.g.e.g. Vector<Number>Vector<Number> is unrelated to is unrelated to Vector<Integer>Vector<Integer>..

• Parametric classes and methods are implemented using “type Parametric classes and methods are implemented using “type erasure”; every reference to a generic type variable is replaced erasure”; every reference to a generic type variable is replaced by its bound. All of the instantiations of a parametric (generic) by its bound. All of the instantiations of a parametric (generic) classes are implemented by a single erased class. Similarly, all classes are implemented by a single erased class. Similarly, all of the instantiations of a polymorphic method are implemented of the instantiations of a polymorphic method are implemented by a single erased method.by a single erased method.

Page 8: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Understanding Type Understanding Type ErasureErasure

• In essence, type erasure translates parameterized code to the In essence, type erasure translates parameterized code to the standard idiom used to simulate genericity in ordinary Java, standard idiom used to simulate genericity in ordinary Java, e.g.e.g.,,

Vector<Integer> VectorVector<Integer> Vectoraugmented by casts where required; theseaugmented by casts where required; thesegenerated casts never fail.generated casts never fail.

• Technical complications: compiler must bridge methods to Technical complications: compiler must bridge methods to connect parametric and erased signatures for a method. The connect parametric and erased signatures for a method. The parametric signature appears in byte code when a class parametric signature appears in byte code when a class AA extends extends an instantiated generic class an instantiated generic class B<E>B<E>, , e.g.e.g.

class Environment extends Vector<Binding> {class Environment extends Vector<Binding> {……public Binding elementAt(int i) { … }public Binding elementAt(int i) { … }

}}

Page 9: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

What Java 5.0 Generics What Java 5.0 Generics OmitOmit• Absence of run-time types inconsistent with Absence of run-time types inconsistent with

naked type parameters and built-in array naked type parameters and built-in array type:type:

new T(), new T[], new T[][],new T(), new T[], new T[][], … are all invalid. … are all invalid.

• Absence of run-time types inconsistent with Absence of run-time types inconsistent with run-time type tests provided by Java:run-time type tests provided by Java:

instanceof Vector<T>instanceof Vector<T> is invalid. is invalid.

(Vector<T>)(Vector<T>) and and (T)(T) are invalid. are invalid.

Exception types cannot be parametric.Exception types cannot be parametric.

• Per-class-instance static fields not an option.Per-class-instance static fields not an option.

Page 10: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Do Run-time Generic Types Matter?

• Isolated parametric allocation [hacked API’s]new T(), new T[], new T[][], ... .

• Parametric casts [JSR14](T) ... , (T[]) … , (Vector<T>) … , … .

• Instantiated casts [cloning, integration of legacy code] (Vector<Integer>) ... , (List<Number>) … , … ..

• Per-class-instantiation static fields (singletons!)

Yes. Awkwad to code around absence of:

Page 11: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Co-variant Wild Card Co-variant Wild Card TypesTypes• New form of parameterized type that New form of parameterized type that

allows a wildcard (“allows a wildcard (“**”) as a type ”) as a type argument in paramterized type, argument in paramterized type, e.ge.g., ., Vector<*>Vector<*>..

• Every usage of the wildcard operator Every usage of the wildcard operator has an upper bound (has an upper bound (ObjectObject by default). by default).

• Contra-variant form is analogous but Contra-variant form is analogous but rarely used.rarely used.

Page 12: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

More General Approach: NextGen (Allen, Cartwright, and Steele)

• Supports exactly the same extension syntax as Java 1.5, less the restrictions.

• All types are available at run-time for casting and instanceof tests.

• Lightweight homogeneous (code shared across parametric instantiations) implementation.

• Performance of prototype compiler is encouraging.

Page 13: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

NextGen Implementation Strategy

• Use lightweight “instantiation” classes (generated on demand) to specify run-time types

• Replace type dependent operations in base classes by abstract methods (snippets)and override them in instantiation classes

Augment GJ implementation relying on type-erasure.

Page 14: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

ObservationsObservations

• Performance difference between different Performance difference between different JVM’s is much greater than difference JVM’s is much greater than difference between GJ, NextGen, and Java.between GJ, NextGen, and Java.

• Implementation tuning of JIT can eliminate Implementation tuning of JIT can eliminate essentially all of the performance penalty essentially all of the performance penalty through code specialization and method through code specialization and method inlining.inlining.

• Specialization provides opportunity for Specialization provides opportunity for performance gains! Explicit generic type performance gains! Explicit generic type information provides guidance on how code information provides guidance on how code should be specialized.should be specialized.

Page 15: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Beyond NextGenBeyond NextGen• Object inlining of boxed primitive Object inlining of boxed primitive

types (easy to do with new wrapper types (easy to do with new wrapper classes).classes).

• Full Genericity: using parameterized Full Genericity: using parameterized types anywhere that they are types anywhere that they are sensible. Only significant restriction sensible. Only significant restriction on use of generic types in NextGen:on use of generic types in NextGen:

class C<T implements I> extendsclass C<T implements I> extends T T

Page 16: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Why MixinsWhy Mixins• Mixins allow programs to abstract directly Mixins allow programs to abstract directly

over uniform class extensions over uniform class extensions [decorator [decorator pattern is the Java workaround for this limitation]pattern is the Java workaround for this limitation]..

class AddScrollBar<T implements Window> extends class AddScrollBar<T implements Window> extends TT implements ScrollableWindow { …} implements ScrollableWindow { …}

• Mixins provide the machinery for defining Mixins provide the machinery for defining a components within the language as a components within the language as generic classes:generic classes:class Module<class Module<BB> {> {

[static] class A extends [static] class A extends BB {…} {…}……

}}

Page 17: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Semantics of Mixins: Two Semantics of Mixins: Two OptionsOptions1. Raw macro-expansion (C++

templates)– Performed on demand (lazily) by class loader– Lacking in hygiene

2. Hygienic macro-expansion– Methods in superclass argument are renamed

to avoid accidental overriding

– Example: class AddHiddenProperty<T implements Widget> extends T

implements Hideable { private boolean isHidden = false; public boolean isHidden() { return isHidden; } public void setHidden(boolean b) { isHidden = b; }

}

What if T already contains the method public boolean isHidden()

Page 18: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Type Checking for Mixins

• Hygienic formulation is straightforward; legality of a mixin application only depends on whether the type arguments satisfy their specified bounds.

• Non-hygienic case is more difficult; a type argument may contain a method that conflicts with a method introduced in a mixin. It is doubtful that these constraints can be checked by a class compiler (like javac) because type arguments can flow across a program via type application.

Page 19: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Challenging issue in mapping mixin genericity onto the JVMConstraints:

• Compatible with existing Java binaries.

• Must enforce mixin hygiene by systematically renaming some methods in the class loader to avoid accidental overriding.

• Extension of the existing NextGen implementation.

Page 20: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Strategy

In class loader, rename all methods m in all classes byIn class loader, rename all methods m in all classes byprefixing them with the mangled name of the class inprefixing them with the mangled name of the class inwhich they are introduced.which they are introduced.

Example: method name Example: method name value in class interp.Interp in class interp.Interp becomesbecomes

$interp$Interp$value

Complicationbridge methods for interface methodsmust forward method dispatches on interface types to

corresponding methods in classes

Page 21: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Implementation Subtleties

1. Same method signature may appear in different interfaces, e.g.

interface I { …; void next(); …} interface J { …; void next(); …} class C implements I { } class Foo<T> extends T implements J { }

Consider: Foo<C> Implements both I.next() and J.next()Must include forwarding methods for both.

Solution: class loader prefixes names of methods ininterfaces by the interface name where they are introduced. This extension will also enable us tosupport multiple “per-interface” definitions for agiven method signature in a class in Java source.

Page 22: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Implementation Subtleties (cont.)2. In principle, several different instantiations of the

same generic interface could be implemented by a class in a source program. Java 5.0 and NextGen disallow these programs because we cannot distinguish the methods after erasure. It rarely happens in practice, but it is a corner case that we must handle. (Failure on class loading is not a very satisfactory solution.)

Question: can we eliminate this restriction in our extension of NextGen to support mixins?

Page 23: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Supporting Multiple Instantiations of the Same Interface

We can modify the NextGen compiler to use instantiated interfaces instead of erased interfaces in both type declarations and the prefixing of method names in interfaces. This approach introduces some extra code because it significantly reduces code sharing. Every interface method call with a receiver type that is an instantiated interface with a free type variable must be implemented by a snippet (since the snippet code will call different methods for different receiver types).

Page 24: Java Generics Robert “Corky” Cartwright Rice University 19 Jan 2005

Status of ProjectStatus of Project• Beta release of NextGen compiler should be Beta release of NextGen compiler should be

available within the next month from available within the next month from www.cs.rice.edu/~javapltwww.cs.rice.edu/~javaplt

Based on Sun Java 1.5 compiler. Based on Sun Java 1.5 compiler. Distribution is binary only at this point.Distribution is binary only at this point.

• Prototype of MixGen (NextGen + Mixins) will Prototype of MixGen (NextGen + Mixins) will be ready for internal testing by the end of be ready for internal testing by the end of Spring.Spring.

• Beta release of MixGen during the summer.Beta release of MixGen during the summer.