Taming Wildcards in Javas Type System Ross Tate Alan Leung Sorin Lerner University of California, San Diego
Why Use Wildcards? long average(List nums) { long sum = 0; for (Object num : nums) sum += ((Number)num).longValue(); return sum / nums.size(); } Runtime Type Cast long average(List Number nums) { long sum = 0; for (Number num : nums) sum += num.longValue(); return sum / nums.size(); } What about List Integer ? P extends Number long average(List P nums) { long sum = 0; for (Number num : nums) sum += num.longValue(); return sum / nums.size(); } Used only once long average(List ? extends Number nums) { long sum = 0; for (Number num : nums) sum += num.longValue(); return sum / nums.size(); } Not covariant Need use-site variance
Why Use Wildcards? P void addSuperclasses(Class P c, List ? super Class ? super P list) { Class ? super P sup = c.getSuperclass(); if (sup != null) { list.add(sup); addSuperclasses(sup, list); } Inexpressible with polymorphism Untypeable with use-site variance X : X : > P. Class X
Open Problems with Wildcards No known subtyping algorithm Subtyping rules are overly restrictive Join algorithm is incomplete Type checker is non-deterministic Type checker can affect program semantics Solved
Broken Subtyping Algorithm class C P extends D D ? super C L P {} C X < : D ? super C X class Numbers P extends Number extends ArrayList P {} List Numbers ? < : List ? extends List ? extends Number javac Stack Overflow Java No javac No Java Yes
False Negatives List ? extends List ? extends Number List ? extends List ? List ? extends ArrayList ? List ? extends Numbers ? List Numbers ? class Numbers P extends Number extends ArrayList P {} extends Number direct supertype extends Number
Our Algorithm List Numbers ? < : List ? extends List ? extends Number Numbers ? < : List ? extends Number Numbers X < : List ? extends Number List X < : List ? extends Number X < : Number class Numbers P extends Number extends ArrayList P {} X < : Number Context Sound & Complete Instantiation Inheritance Opening Instantiation Assumption (if it terminates)
Non-Termination C X < : D ? super C X D D ? super C L X < : D ? super C X C X < : D ? super C L X D D ? super C L X < : D ? super C L X C L X < : D ? super C L X class C P extends D D ? super C L P {} Inheritance Instantiation Infinite Proof of Subtyping Infinite Proof of Subtyping
Restrictions Inheritance Restriction No use of ? super in the inheritance hierarchy Parameter Restriction When constraining type parameters, ? super may only be used at covariant locations class C P extends D D ? super C L P {} P extends List List ? super C L P Termination Guaranteed
Survey Wildcards in InheritanceWildcards in Constraints Only Unconstrained Wildcards # of Superclass Declarations 9.2 Million Lines of Code Analyzed No Violations of Our Restrictions No Violations of Our Restrictions All at covariant locations
Summary of Contributions Sound and Complete Subtyping Algorithm given practical language restrictions Theory of Existential Types design of implicit constraints Techniques for Type-Argument Inference lazy joins for wildcards Fixes to the Type System improved equivalence and intersections Compatible Extensions to Java mixing use-site and declaration-site variance