1) As a general design rule, objects that represent values should be
immutable.
There are a lot of practical advantages to having immutable value
objects: you can use them safely in sets and as keys in maps, you can
pool and flyweight them, and yes, they're much safer in a multi-
threaded environment. But these are side-effects of the fact that
making something immutable makes it an order of magnitude simpler,
conceptually.
The number 6 should always be the number 6. The string "blah" should
always be the string "blah". It doesn't make sense to redefine the
number 6 to have a value of 7. Values are concrete, and that
concreteness gives you the confidence that 6 + 7 will _always_ give
you the same result, whenever you happen to calculate it.
(A friend of mine once told me of a project, I can't remember in which
language, where somebody accidentally redefined the empty string.
Hilarity ensued.)
2) Immutable objects are _safer_ than "thread-safe" objects
When an object says it is thread safe (StringBuffer, for example, or
the pre-1.2 collection classes), all it means is that the _internal
state of the object will remain consistent_ if the object is used
across multiple threads. It doesn't mean that the object itself can be
used across threads safely. For example, the following (admittedly
artificial) code:
public static BigInteger triple(BigInteger int)
{
return int.add(int).add(int);
}
This method is only reliable because BigInteger is immutable. Even if
you were to synchronize every single method on your mutable BigInteger
class, you would not be protecting it from having its value changed
halfway through the operation, leaving you with a value that isn't
three times anything, let alone the number you passed in.
The safety that is generally promised by "thread safe" objects is such
a weak kind of safety that it is largely being abandoned as a feature
of the Java standard libraries. For the very rare case where internal
consistency across threads may be all that is required, wrappers like
Collections.synchronizedFoo() are provided.
It's really no accident that functional languages like Erlang, where
everything is an immutable value, are being touted as the safe
solution to multi-threaded programming. Safe multi-threaded
programming is HARD, and the more code you write that is provably
safe, the fewer times you're going to be up at 3am cursing at your
debugger.
There are a lot of really interesting papers out there about how
mechanisms like Java synchronization are simply the wrong way to deal
with the inherently non-deterministic nature of concurrent
applications, and inevitably lead to disaster, ruination and death.
3) Immutable objects are less efficient than mutable ones... but most
of the time you don't care.
Object allocation in Java is distressingly cheap. Garbage-collection
of young generation objects is reasonably inexpensive. The Java
language is _designed_ with the creation and destruction of lots of
little objects in mind, and it does it very well. As such, it makes
sense to err on the side of creating too many objects.
There are, of course, exceptions. That's why we profile code. For the
most common case where immutability can be a problem -- building
strings -- Java offers a mutable StringBuilder. This is a pretty
common pattern: offer a builder class to construct objects piecemeal,
then have the immutable value pop out of the other end.
You've found a case where the immutable bignum classes in Java aren't
efficient enough for you, and the only alternative you have is to
abandon them and mess with arrays. The problem here isn't that
BigInteger and BigDecimal are immutable, having them be immutable is
the Right Thing To Do. The real problem is that providing a high-
performance library for arbitrary precision arithmetic would _also_ be
the Right Thing To Do, but Java doesn't.
I'm sure some exist, though. Have you tried Googling?
C
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/email@hidden