1 / 48

Javari: Adding Reference Immutability to Java

Javari: Adding Reference Immutability to Java. Matthew Tschantz and Michael Ernst MIT CSAIL. Protecting method arguments. static void print( readonly Date d) { ... // Cannot modify d } String toString() readonly { ... // Cannot modify the receiver }.

zalman
Download Presentation

Javari: Adding Reference Immutability to Java

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL

  2. Protecting method arguments static void print(readonly Date d) { ... // Cannot modify d } String toString() readonly { ... // Cannot modify the receiver }

  3. Protecting abstract state: observer methods class Class { private Object[] signers; readonly Object[] getSigners() { return signers; // JDK 1.1 bug } } myClass.getSigners()[0] = “Sun”;

  4. Protecting abstract state: observer methods class Class { private Object[] signers; readonly Object[] getSigners() { return signers; // Fixes JDK 1.1 bug } } myClass.getSigners()[0] = “Sun”; // Error

  5. Reference immutability • A given reference cannot be used to modify its referent • other references to the object may modify it • Is deep: the transitively reachable state (the abstract state) is protected • Statically type checkable

  6. Reference immutability versus object immutability Object immutability: an object cannot be modified through any reference Graph temp = new Graph(); // construct the graph readonly Graph g = temp; temp = null;

  7. Motivation • Provide compiler-enforced guarantees that a method will not change a given parameter • Protect an object’s abstract state • Prevent/detect errors • Documentation • Enable analyses and transformations

  8. Other work • C++: • unsound (unchecked casts) • non-transitive • no parametric polymorphism • JAC [Kniesel 2001]: • unsound (subtyping, arrays) • return type mutability equals receiver's • Javari2004 [Birka 2004]: • no parametric polymorphism • conflates assignability and mutability • Object immutability • restricts programmer

  9. Outline • Language overview • assignability • mutability • Parametric polymorphism • Formal model • Other language features • Conclusion

  10. Language overview readonly Immutable reference assignable Field may be reassigned even through a read-only reference mutable Field may be mutated even through a read-only reference

  11. Readonly readonly Date rd = new Date(); rd.year = 2005; // Compile-time error rd.incrementDay(); // Compile-time error rd = new Foo(); // OK

  12. Mutability versus assignability • Assignability • not part of the type • final • Mutability • part of the type • readonly final Date fd = null; readonly Date rd = null; fd = new Date(); // Error: final rd = null; // OK Date d1 = fd; // OK Date d2 = rd; // Error: wrong type

  13. Type system Every type (mutable) T has readonly T as a supertype readonly Object /*mutable*/ Object readonly Date /*mutable*/ Date

  14. Outline • Language overview • assignability • mutability • Parametric polymorphism • Formal model • Other language features • Conclusion

  15. Assignability Whether a reference may be assigned to. class Appointment { final Date time; // Same as in Java assignable int room; } Appointment appoint; appoint.time = new Date(); //Error appoint.room = 250; //OK

  16. Assignability modifiers final: May never be assigned assignable: May always be assigned; the default for locals this-assignable: • May be assigned through a mutable reference • May not be assigned through a readonly reference • Only applicable to fields; the default • The assignability depends on the mutability of the enclosing object: “this”

  17. Assignability example class Bicycle { final int id; // Never changes assignable int hashCode; // A cache /*this-assign*/ int gear; // Abstract state } /*mutable*/ Bicycle b; readonly Bicycle rb;

  18. final class Bicycle { final int id; // Never changes assignable int hashCode; // A cache /*this-assign*/ int gear; // Abstract state } /*mutable*/ Bicycle b; readonly Bicycle rb; b.id = 5; // Error rb.id = 5; // Error

  19. assignable class Bicycle { final int id; // Never changes assignable int hashCode; // A cache /*this-assign*/ int gear; // Abstract state } /*mutable*/ Bicycle b; readonly Bicycle rb; b.hashCode = 5; // OK rb.hashCode = 5; // OK

  20. this-assignable class Bicycle { final int id; // Never changes assignable int hashCode; // A cache /*this-assign*/ int gear; // Abstract state } /*mutable*/ Bicycle b; readonly Bicycle rb; b.gear = 5; // OK

  21. this-assignable class Bicycle { final int id; // Never changes assignable int hashCode; // A cache /*this-assign*/ int gear; // Abstract state } /*mutable*/ Bicycle b; readonly Bicycle rb; b.gear = 5; // OK rb.gear = 5; // Error

  22. Outline • Language overview • assignability • mutability • Parametric polymorphism • Formal model • Other language features • Conclusion

  23. Mutability Whether an object’s transitive abstract state may be modified class Date { /*this-assignable*/ int year; } /*mutable*/ Date d; readonly Date rd; d.year = 2005; //OK rd.year = 2005; //Error

  24. Mutability modifiers readonly: May never be mutated mutable: May always be mutated; the default for locals this-mutable: • May be mutated through mutable reference • May not be mutated through readonly references • Only applicable to fields; the default • The mutability depends on the mutability of the enclosing class: “this”

  25. Mutability example class Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal; } /*mutable*/ Account a; readonly Account ra;

  26. readonly class Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal; } /*mutable*/ Account a; readonly Account ra; a.owner.setName(“Bob”); // Error ra.owner.setName(“Bob”); // Error

  27. mutable mutable excludes requests from the abstract state of the object class Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal; } /*mutable*/ Account a; readonly Account ra; a.requests.add(“checkBalance”); // OK ra.requests.add(“checkBalance”); // OK

  28. this-mutable class Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal; } /*mutable*/ Account a; readonly Account ra; a.balance.withdraw(1000); // OK

  29. this-mutable class Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal; } /*mutable*/ Account a; readonly Account ra; a.balance.withdraw(1000); // OK ra.balance.withdraw(1000); // Error

  30. this-mutable fields reached through a readonly reference readonly, right?

  31. this-mutable fields reached through a readonly reference readonly, right? NO, would result in type loophole allowing one to convert a readonly reference to a mutable reference:

  32. this-mutable fields reached through a readonly reference readonly, right? NO, would result in type loophole allowing one to convert a readonly reference to a mutable reference: class Student { assignable /*this-mut*/ GradeReport grades; } /*mutable*/ Student s = new Student(); readonly Student rs = s; readonly GradeReport rg; /*mutable*/ GradeReport g; rs.grades = rg; //readonly assigned to this-mutable g = s.grades; //this-mutable assigned to mutable

  33. this-mutable fields reached through a readonly reference Solution: Disallow readonly references to be assigned to a this-mutable field class Student { assignable /*this-mut*/ GradeReport grades; } this-mutable fields are • taken out at readonly GradeReport • written to as mutable GradeReport

  34. this-mutable fields reached through a readonly reference Solution: Disallow readonly references to be assigned to a this-mutable field class Student { assignable /*this-mut*/ GradeReport grades; } this-mutable fields are • taken out at readonly GradeReport • written to as mutable GradeReport Using wildcards and bounds, the type of grades can be written as: <? extends readonly GradeReport super mutable GradeReport> Notation: <? readonly GradeReport>

  35. Outline • Language overview • assignability • mutability • Parametric polymorphism • Formal model • Other language features • Conclusion

  36. Uses of parametric classes Local variable declarations: /*mut*/ List</*mut*/Date> a; // add, mutate /*mut*/ List<readonlyDate> b; // add readonly List</*mut*/ Date> c; // mutate readonly List<readonlyDate> d; // neither (Arrays are similar)

  37. Inside parametric classes Type arguments include mutability Library cannot write: class C<T> { mutable T x; } C<readonly Date> y; // Conflicting types

  38. Inside parametric classes Type arguments include mutability Library cannot write: class C<T> { mutable T x; } C<readonly Date> y; // Conflicting types Library can force a mutable type using a bound: ; class C<T extends mutable Object> { T x; }

  39. this-mutable type arguments class Wheel { /*this-mut*/ List</*this-mut*/Spoke> spokes; } /*mutable*/ Wheel w; readonly Wheel rw; w.spokes has type /*mut*/ List</*mut*/ Spoke> /*mut*/ List</*mut*/ Spoke> w = w.spokes; // OK

  40. this-mutable type arguments class Wheel { /*this-mut*/ List</*this-mut*/Spoke> spokes; } /*mutable*/ Wheel w; readonly Wheel rw; rw.spokes has type ? readonly List<? readonly Spoke> readonly List<?readonly Spoke> x = rw.spokes; // OK readonly List<readonlySpoke> y = rw.spokes; // Error readonly List</*mutable*/ Spoke> z = rw.spokes; // Error

  41. Outline • Language overview • assignability • mutability • Parametric polymorphism • Formal model • Other language features • Conclusion

  42. Formal model • Core language • Extension to Featherweight Generic Java • Type soundness proof underway • Subject reduction and progress theorems • Proof that an object is never modified if only a readonly reference exists

  43. Outline • Language overview • assignability • mutability • Parametric polymorphism • Formal model • Other language features • Conclusion

  44. Reflection • Method.invoke continues to return mutable references • dynamically checks type signature: return type must be mutable • New method Method.invokeReadonly returns a readonly reference • no dynamic checks • Type, including mutability, of arguments (including receiver) is checked at compile time.

  45. Serialization • Add a readonly-ness bit to the serialized form. • Check readonly-ness bit if one attempts to deserialization an object to a mutable reference.

  46. Reducing code duplication romaybe keyword templates over methods class Conference { /*this-mutable*/ Date d; We wish to write two (overloaded) methods: readonly Date getDate() readonly { return d; } /*mutable*/ Date getDate() /*mutable*/ { return d; } Syntactic sugar: romaybe Date getDate() romaybe { return d; } }

  47. Outline • Language overview • assignability • mutability • Parametric polymorphism • Formal model • Other language features • Conclusion

  48. Contributions • Transitive reference immutability • Distinguishes assignability and mutability • Formal model • Type system for full Java including parametric polymorphism, reflection, and serialization • Templates to reduce code duplication • Interoperable with Java

More Related