On 18 May 2011 17:58, Matt Benson <[email protected]> wrote: > On Wed, May 18, 2011 at 11:47 AM, Stephen Colebourne > <[email protected]> wrote: >> This issue about what immutable means wrt "final" on the class has >> bounced around a few threads. >> >> In my view, immutable has a specific meaning, whereby the object is >> unequivically safe to use and share between threads. To do so, there >> are certain rules. One that is disputed is whether the class must be >> final. eg. http://www.javapractices.com/topic/TopicAction.do?Id=29 >> >> Josh Bloch in Effective Java recommends using final on the class where >> possible, but offers the alternative of a private or package scoped >> constructor with a public static factory. He does not recommend a >> public constructor (even when accompanied by defining all the methods >> as final). >> >> The issue arises with a method that takes an ImmutableFoo as an >> argument where ImmutableFoo is supposed to be "immutable". >> >> public void doStuff(ImmutableFoo foo) {...} >> >> This author of this method might pass the object to another thread for >> processing following the expectation that the class is immutable (from >> the class name and/or Javadoc). >> >> But, someone could pass in the following class to that method: >> >> public EvilFoo extends ImmutableFoo { >> public StringBuilder buf; >> public EvilFoo(StringBuilder buf) { >> this.buf = buf; >> } >> } >> >> The user can now access EvilFoo in multiple threads at the same time. >> >> This problem afflicts BigDecimal and BigInteger. The only way to >> safely use those classes (wrt threading) is to write the following: >> >> public void processNumber(BigDecimal bd) { >> if (bd.getClass() != BigDecimal.class) { >> bd = new BigDecimal(bd.toString()); // or some other conversion >> technique >> } >> .... >> } >> >> Most users do not do this, so their usage of BigDecimal is not >> actually thread-safe (or safe against a clever hack). >> >> Given all the above, we in Commons and [lang] should take the lead, >> and only declare something as "immutable" if it really is - which >> generally means final fields and final class. >> > > I generally agree that this makes sense. Our ImmutablePair is part of > the way there in that its left/right _fields_ are final, assigned from > the single constructor offered. The only danger points I can > currently see are the implementations of > getLeft()/getRight()/setValue(). Now, AIUI, Gary's interest in > extending ImmutablePair is overriding stuff like toString(). Can we > satisfy everyone by making these methods final, such that an > ImmutablePair will behave as Stephen recommends, while permitting > subclasses to perform unrelated operations?
See the EvilFoo example above. Any ability to subclass, even with safe methods, means its not completely thread-safe. Stephen --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
