Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Javari: Adding Reference Immutability to Java Matthew Tschantz & Michael Ernst (MIT) OOPSLA’05 Presented by Tali Shragai 1 Extension to Javari2004 [Birka] Javari: Java + (C++ const) + more… OOPSLA’04: Initial Javari implementation Experience: 160,000 code lines Two new keywords: readonly, mutable Better documentation Error detection and prevention Compatible with Java & existing JVMs But: No Generics, serialization, reflection Confuses mutability & assignability Javari 05: More keywords: assignable, romaybe Genericity, reflection, serialization Most important (?): mutability vs. assignability 2 Protecting method arguments A library routine does not modify its 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; Object[] getSigners() { return signers; // JDK 1.1 security hole } } myClass.getSigners()[0] = “Sun”; 4 Protecting abstract state: observer methods (revised) class Class { private Object[] signers; readonly Object[] getSigners() { return signers; // Fixes JDK 1.1 bug } } myClass.getSigners()[0] = “Sun”; // Error 5 Reference vs. Object immutability Reference immutability Object modification: Deep: cannot modify transitively reachable state Static type checking! Readonly reference: no! Other reference: yes. Dynamic checking for mutability downcasts Object immutability: write protect from any reference Graph temp = new // construct the readonly Graph g temp = null; // further usage Graph(); graph = temp; through read only reference… Javari: object immutability emulated by reference immutability 6 Related work Old trick: pass/return by value C++: const, const_cast pain for large objects Unsound (unchecked casts) Non-transitive! No immutability-based parameterization Leads to code duplication (const methods) No support for multidimensional arrays? JAC [Kniesel 2001]: Implementation requires rewriting the code Unsound (subtyping, arrays) Return type mutability equals receiver's 7 Protection methods Level Java C++ Javari Level 1 assignment final Foo a const Foo *a final Foo a Level 2 mutability Foo const *a readonly Foo a Level 3 const Foo const *a final readonly Foo a … Level ∞ Transitive protection! 8 Yield protection Level Java C++ Javari Level 1 mutable Foo *a assignable Foo a Level 2 mutable Foo a 9 Readonly readonly Date rd = new Date(); rd.year = 2005; // Compile-time error rd.incrementDay(); // Compile-time error rd = new Foo(); // OK 10 Mutability vs. Assignability Mutability Assignability part of the type not part of the type may abstract state mutate? can be lvalue in assignment? readonly final final Date fd readonly Date rd fd = new Date(); rd = null; Date d1 = fd; Date d2 = rd; = null; = null; // Error: final // OK // OK // Error: wrong type 11 Type system Every type (mutable) T has readonly T as a supertype readonly Object /*mutable*/ Object readonly Date /*mutable*/ Date 12 Immutable classes A class/interface can be declared immutable using readonly in its class declaration. Non-static fields & methods readonly (default) Reference to its objects implicitly read-only Subclasses must be immutable too! readonly class String{…} /*readonly*/ String s1 = new String(); readonly String s2 = new String(); S1 = s2; S2 = s1; // OK // OK 13 Assignability May a reference 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 14 Assignability modifiers final: May never be assigned assignable: May always be assigned (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” 15 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; 16 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 Resolved assignability of ref.f Declared assignability of f final Resolved mutability of ref mutable readonly unassignable unassignable 17 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 Resolved assignability of ref.f Declared assignability of f Resolved mutability of ref mutable readonly final unassignable unassignable assignable assignable assignable 18 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 Resolved assignability of ref.f Declared assignability of f Resolved mutability of ref mutable readonly final unassignable unassignable assignable assignable assignable this-assignable assignable unassignable 19 Mutability May the object’s transitive abstract state be modified? class Date { /*this-assignable*/ int year; } /*mutable*/ Date d; readonly Date rd; d.year = 2005; // OK rd.year = 2005; // Error 20 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” 21 Mutability example class Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal; } /*mutable*/ Account a; readonly Account ra; 22 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 Mutability of ref.f Declared mutability of f readonly Resolved mutability of ref mutable readonly readonly readonly 23 mutable class Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal; mutable excludes requests from the } abstract state of the /*mutable*/ Account a; object readonly Account ra; a.requests.add(“checkBalance”); // OK ra.requests.add(“checkBalance”); // OK Mutability of ref.f Declared mutability of f Resolved mutability of ref mutable readonly readonly readonly readonly mutable mutable mutable 24 this-mutable class Account { readonly Customer mutable RequestLog /*this-mut*/ Balance } /*mutable*/ Account a; readonly Account ra; a.balance.withdraw(1000); owner; requests; bal; // OK Declared mutability of f Resolved mutability of ref mutable readonly readonly readonly readonly mutable mutable mutable this-mutable mutable ? 25 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 Mutability of ref.f Declared mutability of f Resolved mutability of ref mutable readonly readonly readonly readonly mutable mutable mutable this-mutable mutable readonly? 26 this-mutable fields reached through a readonly reference readonly, right? 27 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: 28 this-mutable fields reached through a readonly reference rs Readonly assignable Readonly?? grades s Non-readonly class Student { assignable /*this-mut*/ GradeReport grades; } /*mutable*/ Student s = new Student(); readonly Student rs = s; readonly GradeReport rg; /*mutable*/ GradeReport g; Downcast rs.grades = rg; //readonly assigned to this-mutable g = s.grades; //this-mutable assigned to mutable 29 this-mutable fields reached through a readonly reference Solution: Disallow readonly references to be assigned to a this-mutable field this-mutable fields through readonly reference are: readonly as rvalue (may only be assigned to a readonly reference) mutable as lvalue (may only be assigned with mutable reference) Notation: <? readonly GradeReport> 30 Uses of parametric classes Local /*mut*/ /*mut*/ readonly readonly variable declarations: List</*mut*/ List<readonly List</*mut*/ List<readonly Date> Date> Date> Date> a; b; c; d; // // // // add, mutate add mutate neither 31 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; } 32 this-mutable type arguments class Device { /*this-mut*/ List</*this-mut*/ Driver> drivers; } /*mutable*/ Device d; readonly Device rd; d.drivers /*mut*/ has type /*mut*/ List</*mut*/ Driver> List</*mut*/Driver> dl = d.drivers; // OK 33 this-mutable type arguments class Device { /*this-mut*/ List</*this-mut*/ Driver> drivers; } /*mutable*/ Device d; readonly Device rd; rd.drivers has type ? readonly List<? readonly Driver> readonly List<? readonly Driver> x = rd. drivers; readonly List<readonly Driver> y = rd. drivers; readonly List</*mutable*/Driver> z = rd. drivers; //OK //Error //Error 34 Serialization Add a readonly-ness bit to the serialized form. De-serialization done using 2 versions of ObjectInputStream.readObject: readObjectReadonly – returns a read-only object, without checking. readObject – returns a mutable objects, but throws an exception if the readonly-ness bit is set. 35 Reducing code duplication In Java, each class definition defines exactly one type. In Javari, by contrast, a class C actually denotes 2 type: C and readonly C. 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;} } 36 Downcasts Javari guarantees that a readonly reference cannot be used, directly or indirectly, to modify its referent. Down-casting a reference from readonly to mutable triggers runtime checks, which disallow any modifications done through the casted reference. 37 Downcast example class Foo{ Date d; void setD() /*mutable*/{ d = new Date(); } } Foo f1 = new Foo(); readonly Foo rf = f1; Foo f2 = (mutable)rf; f1.d = new Date(); // OK f2.d = new Date(); // run-time error f1.setD(); // OK F2.setD(); // run-time error 38 Contributions Transitive reference immutability Distinguishes assignability and mutability Formal model (not shown here) Type system for full Java 5.0 including parametric polymorphism, reflection, and serialization Templates to reduce code duplication Interoperable with Java Still to come: type inference… 39 The End! Thank you for listening… 40