120 likes | 286 Views
Taming Wildcards in Java’s Type System. Ross Tate Alan Leung Sorin Lerner. University of California, San Diego. Why Use Wildcards?. Not covariant. Need use-site variance. Used only once. What about List 〈 Integer 〉 ?. long average(List nums) { long sum = 0; for (Object num : nums)
E N D
Taming Wildcardsin Java’s Type System Ross Tate Alan Leung Sorin Lerner University of California, San Diego
Why Use Wildcards? Not covariant Need use-site variance Used only once What about List〈Integer〉? long average(List nums) { long sum = 0; for (Object num : nums) sum += ((Number)num).longValue(); return sum / nums.size(); } long average(List〈Number〉 nums) { long sum = 0; for (Number num : nums) sum += num.longValue(); return sum / nums.size(); } 〈P extends Number〉 long average(List〈P〉 nums) { long sum = 0; for (Number num : nums) sum += num.longValue(); return sum / nums.size(); } long average(List〈? extends Number〉 nums) { long sum = 0; for (Number num : nums) sum += num.longValue(); return sum / nums.size(); } Runtime Type Cast
Why Use Wildcards? Inexpressible with polymorphism 〈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); } } Untypeable with use-site variance ∃X : X :> P. Class〈X〉
Open Problems with Wildcards Solved • No known subtyping algorithm • Subtyping rules are overly restrictive • Join algorithm is incomplete • Type checker is non-deterministic • Type checker can affect program semantics
Broken Subtyping Algorithm class Numbers〈P extends Number〉 extends ArrayList〈P〉 {} List〈Numbers〈?〉〉<: List〈? extends List〈? extends Number〉〉 No javac Java Yes class C〈P〉 extends D〈D〈? super C〈L〈P〉〉〉〉 {} C〈X〉<: D〈? super C〈X〉〉 No Stack Overflow javac Java
False Negatives class Numbers〈P extends Number〉 extends ArrayList〈P〉 {} List〈? extends List〈? extends Number〉〉 List〈? extends List〈?〉〉 List〈? extends ArrayList〈?〉〉 List〈? extends Numbers〈?〉〉 List〈Numbers〈?〉〉 extends Number direct supertype extends Number direct supertype extends Number direct supertype
Our Algorithm Sound & Complete (if it terminates) class Numbers〈P extends Number〉 extends ArrayList〈P〉 {} List〈Numbers〈?〉〉<: List〈? extends List〈? extends Number〉〉 Numbers〈?〉<: List〈? extends Number〉 Numbers〈X〉<: List〈? extends Number〉 List〈X〉<: List〈? extends Number〉 X <: Number Instantiation X <: Number Context Opening Inheritance Instantiation Assumption
Non-Termination Contrived class C〈P〉 extends D〈D〈? super C〈L〈P〉〉〉〉 {} 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〉〉〉 Inheritance Infinite Proof of Subtyping Instantiation Inheritance Instantiation
Restrictions Termination Guaranteed Contrived 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〉〉〉〉 {} Contrived 〈P extends List〈List〈? super C〈L〈P〉〉〉〉〉
Survey No Violations of Our Restrictions 9.2 Million Lines of Code Analyzed Wildcards in Inheritance Wildcards in Constraints 10000 100000 1000 0 Only Unconstrained Wildcards # of Superclass Declarations 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