Joshua said:
This is one possible reason:
Since each array is its own special class, the virtual machine has to
synthesize special class objects for arrays. The developers made a
choice to keep these objects as small as possible. One thing that could
really bloat these objects would be to have to define methods for
/every/ single array type.
That's an interesting point. I have to assume however that it would be
possible to play some tricks internally such that the JVM would not have
to bloat itself, but could just use an internal pointer back to a master
routine for each primitive. The worst case should be that an actual
class would not be created unless it had to be serialized or similarly
made external to the JVM.
Not that I think I'm an expert on the JVM internals or anything, just I
don't see how it could be much more complicated than that.
java.util.Array's toString method has 75 bytes for Object[] and 72 for
<primitive>[]. The hashCode methods are between 45 and 56 bytes. The
equals methods are between 54 bytes and 78 bytes.
Even ignoring whether or not you want equals to be == or .equals
equality, that's 206 bytes for just the bytecode operations for an
Object[] class. I'm not including the overhead for method definitions.
OK, 206 bytecodes which exist currently, and which would need to exist
under any system that I can think of.
I'm willing to bet that the code for Object.clone() special-cases array
cloning, just to avoid having to redefine all of these methods.
Fair enough, although I'm not following with the paragraph or the two
before this one why this would discourage adding methods to an array class.
I'd also imagine that this setup makes the code generation easier:
there's only a few bytes that have to be modified, even across primitive
and reference type arrays.
Why modify bytes? You mean for generating new class types? Yes, I'd
assume that it's only necessary to modify a few bytes for a new class
type. Should be that way under any class system.
I'm not trying to be snarky or anything, just trying to understand where
you see a problem.
The JLS says that the type of any array can be reduced to its type and
the number of dimensions:
<
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#46168>
That's all you'd need to store in a new type, in any system. I imagine
that this information could be stored in the array itself. Since a new
type is needed for each array, there's no point to making a separate
object. The relationship is one to one.
extern "C" {
int array_length;
Object array_type;
int num_dimensions;
unsigned char []; // array data
}
Or something like that. Assume that "Objects" have a method
implementing array operations, if Object is a primitive. Not hard for
the low level JVM code to implement. Now you just need one actual copy
of the method per primitive, or 8 total. Ever. Multi-dimensional
arrays just do their multi-dimensional thing that eventually ends up
back at the primitive routine for that type of primitive. Other
Objects, which are full classes, obviously allow full method overriding
in whatever manner the JVM chooses to implement overriding.
Really all I've done here is add a virtual method table for array
primitives. Each array "points back" to it's type, which has the needed
implementations of it's methods. I don't see that part as a great
difficulty. (There are other aspects of this idea that I think would be
much harder.)