Because immutable collections absolutely require sharing to be usable. Otherwise, every single operation drops a whole other list into the heap somewhere. Languages that are entirely immutable, like Haskell, generate astonishing amounts of garbage without aggressive optimizations and sharing. Having collection that's only usable with <50 elements is not worth putting in the standard library.
Further more, immutable collections often have fundamentally different implementations than their mutable counterparts. Consider for example ArrayList
, an efficient immutable ArrayList
wouldn't be an array at all! It should be implemented with a balanced tree with a large branching factor, Clojure uses 32 IIRC. Making mutable collections be "immutable" by just adding a functional update is a performance bug just as much as a memory leak is.
Furthermore, sharing isn't viable in Java. Java provides too many unrestricted hooks to mutability and reference equality to make sharing "just an optimization". It'd probably irk you a bit if you could modify an element in a list, and realize you just modified an element in the other 20 versions of that list you had.
This also rules out huge classes of very vital optimizations for efficient immutability, sharing, stream fusion, you name it, mutability breaks it. (That'd make a good slogan for FP evangelists)
Reflection seems a very fragile and non-intuitive way to implement this. Instead I think you should be telling the objects what to do, and they will collaborate between themselves to determine this. e.g.
restaurant.switchToSpringMenu();
and the Restaurant
object could swap between menu instances that it has.
Exact requirement is that I will be getting some task to be done and
corresponding value.. Now every task can be at different level in the
hierarchy of the class... So I am not how else should I implement this
Perhaps this could be achieved via a visitor pattern. e.g. you do something like:
restaurant.reorganise(forSummer);
where forSummer
is some implementation of a task. The Restaurant
object collaborates with this task object, then calls on the underlying Employee
/Menu
classes, which will do the same.
If you really want a more generic means of navigating these hierarchies, you could look at JXPath, which allows you to use XPath-like expressions to find objects e.g.
(Ingredient)JXPathContext.newContext(restaurants).
getValue("restaurant[address/zipCode='90210']/menu/ingredients[1]");
Best Answer
I can't seem to find any sources of that, but I believe this feature was dropped completely. There are numerous reasons I can think of:
performance - each
void
method now has an extra return opcode and every place where this method is called needs implicitpop
unless it actually uses method chainingbackward compatibility - compiling against this feature suddenly makes the code backward incompatible because the contract of every
void
method has changedOf course this can also be implemented by the compiler (calling method on
void
? You probably meantthis
, let me add this implicitly), don't know what are the disadvantages of this approach.