When I write this
String[] fruits = {"Apple", "Pear"};
I would expect that at compile time the array and the strings are created, like it would happen for similar code in C. Is it correct? Are array and their content generally created at compile time or at run-time?
Arrays, which are objects in Java, are created. This can only occur at runtime.
Note that many objects are created in a Java program, and your object creations occurs only after the VM itself is initialized. One static array initialization isn't going to put a noticeable burden on your performances.
If you don't change the array and you have many instances, be sure to declare it as static :
static String[] fruits = {"Apple", "Pear"};
Note also an important difference with what could be a statically compiled array : the java array is mutable. You can't change its length but you can change its elements (or nullify them). A java array, even final static, isn't really constant.
Arrays are special objects in java. So, they will be created at runtime.
As per Java Language Specification
In the Java programming language, arrays are objects (§4.3.1), are dynamically created, and may be assigned to variables of type Object (§4.3.2)
JLS 15.10 provides more information on array creation expressions.
Related
I'm using a class that has a method that accepts a boolean[].
This code does not raise any errors
public class myclass{
void move(boolean[] myarray) {
//Do stufff
}
}
Now, I do a little C++ coding, and this would not work in the context of dynamic memory.
So this is essentially a java question:
In my case the array being received has a known length, but I want to know how you would handle this in Java if it is dynamic (as well as what I should do if its not dynamic).
I'm guessing the compiler or JVM is going to handle this, but I want to know the speed optimizations I can implement.
Arrays in Java are always constant length. From The Java Tutorials, "The length of an array is established when the array is created."
If you wanted dynamic arrays, you'd use something from the Collections Framework, e.g. ArrayList.
In any case, a reference to the array (or collection) is passed into move(...), so there shouldn't be any difference in speed just for the function call.
When using the array, I'd expect (static) arrays to be dereferenced more quickly than going through the function calls to access elements of (dynamic) collections. However, to have a proper comparison, you'd need to provide more context of how your array is used.
You should consider using ArrayList<>() for all your needs related to iterating arbitrary length collections.
Also using List is a good practice in the Java world. There is a article about programmers who use Lists and arrays and those who use lists tend to produce less bugs.
The Java language specification specifies that
In the Java programming language arrays are objects (§4.3.1), are dynamically created, and may be assigned to variables of type Object (§4.3.2). All methods of class Object may be invoked on an array.
So, considering arrays are objects — why did the Java designers make the decision not to allow inherit and override from it, for example, toString() or equals()?
The current syntax wouldn't allow creating anonymous classes with an array as the base class, but I don't think that was the reason for their decision.
Java was a compromise between non-object languages and very slow languages of that time where everything was an object (think about Smalltalk).
Even in more recent languages, having a fast structure at the language level for arrays (and usually maps) is considered a strategic goal. Most people wouldn't like the weight of an inheritable object for arrays, and certainly nobody wanted this before JVM advances like JIT.
That's why arrays, while being objects, weren't designed as class instances ("An object is a class instance or an array"). There would be little benefit in having the ability to override a method on an array, and certainly not a great-enough one to counterbalance the need to check for the right method to apply (and in my opinion not a great-one enough to counterbalance the increased difficulty in code reading, similar to what happens when you override operators).
I came across UNDER THE HOOD - Objects and arrays which explains almost anything you need to know about how JVM handles arrays. In JVM, arrays are handled with special bytecodes, not like other objects we are familiar with.
In the JVM instruction set, all objects are instantiated and accessed
with the same set of opcodes, except for arrays. In Java, arrays are
full-fledged objects, and, like any other object in a Java program,
are created dynamically. Array references can be used anywhere a
reference to type Object is called for, and any method of Object can
be invoked on an array. Yet, in the Java virtual machine, arrays are
handled with special bytecodes.
As with any other object, arrays cannot be declared as local
variables; only array references can. Array objects themselves always
contain either an array of primitive types or an array of object
references. If you declare an array of objects, you get an array of
object references. The objects themselves must be explicitly created
with new and assigned to the elements of the array.
Arrays are dynamically created objects, and they serve as a container that hold a (constant) number of objects of the same type. It looks like arrays are not like any other object, and that's why they are treated differently.
I'd like to point out this article. It seems as though arrays and objects follow different opcodes. I can't honestly summarize it more than that however it seems, arrays are simply not treated as Objects like we're normally used to so they don't inherit Object methods.
Full credits to the author of that post as it's a very interesting read, both short & detailed.
Upon further digging into the topic via multiple sources I've decided to give a more elaborate version of my previous answer.
The first thing to note that instantiation of Objects and Arrays are very different within the JVM, their follow their respective bytecode.
Object:
Object instantiation follows a simple Opcode new which is a combination of two operands - indexbyte1 & indexbyte2. Once instantiated the JVM pushes the reference to this object onto the stack. This occurs for all objects irrespective of their types.
Arrays:
Array Opcodes (regarding instantiation of an array) however are divided into three different codes.
newarray - pops length, allocates new array of primitive types of type indicated by atype, pushes objectref of new array
newarray opcode is used when creating arrays that involve primitive datatypes (byte short char int long float double boolean) rather than object references.
anewarray - pops length, allocates a new array of objects of class indicated by indexbyte1 and indexbyte2, pushes objectref of new array
anewarray opcode is used when creating arrays of object references
multianewarray - pops dimensions number of array lengths, allocates a new multidimensional array of class indicated by indexbyte1 and indexbyte2, pushes objectref of new array
multianewarray instruction is used when allocating multi-dimensional arrays
Object can be a class instance or an array.
Take from Oracle Docs
A class instance is explicitly created by a class instance creation expression
BUT
An array is explicitly created by an array creation expression
This goes hand in hand with the information regarding the opcodes. Arrays are simply not developed to be class interfaces but are instead explicitly created by array creation expression thus naturally wouldn't implicitly be able to inherit and/or override Object.
As we have seen, it has nothing to do with the fact that arrays may hold primitive datatypes. After giving it some thought though, it isn't very common to come across situations where one might want to toString() or equals() however was still a very interesting question to try and answer.
Resources:
Oracle-Docs chapter 4.3.1
Oracle-Docs chapter 15.10.1
Artima - UnderTheHood
There are many classes in standard java library that you cannot subclass, arrays aren't the only example. Consider String, or StringBuffer, or any of the "primitive wrappers", like Integer, or Double.
There are optimizations that JVM does based on knowing the exact structure of these objects when it deals with them (like unboxing the primitives, or manipulating array memory at byte level). If you could override anything, it would not be possible, and affect the performance of the programs very badly.
This question already has answers here:
Is an array an object in Java?
(14 answers)
Closed 9 years ago.
We know that Arrays are objects in Java. I believe to create an object in Object oriented languages(if not we can have it in a separate discussion), we need a blueprint of it(a class). But I'm not sure or cannot find the class for which the object is being created for arrays when the new operator is used. If there is a class for arrays in java, then how will the hierarchy look like?
If there is no class, then how are the objects instantiated? And what is the reason behind having an object type without a class?
Arrays are created by virtual machine with a special instruction called newarray, so think them as a special construct.
From JVM Spec:
3.9. Arrays
Java Virtual Machine arrays are also objects. Arrays are created and manipulated using a distinct set of instructions. The newarray instruction is used to create an array of a numeric type. The code:
Also read more from JLS for class hierarchy of an array.
The direct superclass of an array type is Object.
An array, let's say an Object[], is a special kind of variable, just as primitives are. Its type is Object[], not Object. Java is not a "fully" object oriented language, such as Ruby is; it has some special data types like arrays and primitives.
The logic is reverse to your.
An object is a class instance or an array.
But as Java is OOP language, everything must be represented as object. When you reflect your code you can use class java.lang.reflect.Array that represent Array.
arrays are not primitive in java. An array is a container object that holds a fixed number of values of a single type.
System.out.print(int[].class.toString());
It successfully prints and proves it has a concrete class in background and same applied for all other array types.
Find documentaion in detail.
Yes, Java has classes for arrays, see http://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html#jls-10.8 Class Objects for Arrays, e.g.
Class<int[]> cls = int[].class;
These classes are dynamically created by JVM.
There is no hierarchy among arrays of primitive types
int[] a = new long[1];
Produces compile time error. The hiearchy of Object array types is the same as with Object types
Object[] a = new String[1];
Is there any reason why an array in Java is an object?
Because the Java Language Specification says so :)
In the Java programming language arrays are objects (§4.3.1), are dynamically created, and may be assigned to variables of type Object (§4.3.2). All methods of class Object may be invoked on an array.
So, unlike C++, Java provides true arrays as first-class objects:
There is a length member.
There is a clone() method which overrides the method of the same name in class Object.
Plus all the members of the class Object.
An exception is thrown if you attempt to access an array out of bounds.
Arrays are instanciated in dynamic memory.
Having arrays be objects means that you can do operations with them (e.g., someArray.count('foo')) instead of just doing it against them (e.g., count(someArray, 'foo')), which leads to more natural syntax.
Another point is that objects are mutable and are passed by reference. In arrays there aren't any fields/methods that you can use to change "properties" of the array, but you sure can mutate the element values. And the benefits of passing arrays by reference are pretty obvious (though functional programmers probably wish Java had immutable lists passed by value).
Edit: forgot to mention. In the period before autoboxing, it was helpful to be able to store arrays in collections, write them to ObjectStreams etc.
Probably because they wanted to get as close as possible to making everything an object. Native types are there for backward compatibility.
So that they get all the benefits thereof:
getHashCode()
toString()
etc.
And arrays aren't 'primitive', so if they can't be primitive, they must be objects.
I'm not sure about the official reason.
However, it makes sense to me that they are objects because operations can be performed on them (such as taking the length) and it made more sense to support these operations as member functions rather than introduce new keywords. Other operations include clone(), the inherited operations of object, etc. Arrays are also hashable and potentially comparable.
This is different from C (and native arrays in C++), where your arrays are essentially pointers to a memory offset.
In Java, an array IS AN Object. My question is... is an Object constructor called when new arrays is being created? We would like to use this fact to instrument Object constructor with some extra bytecode which checks length of array being constructed. Would that work?
Per the JVM spec: "Arrays are created and manipulated using a distinct set of instructions." So, while arrays are instances of Objects, they aren't initialized the same way that other objects are (which you can see if you scroll up from that link anchor).
As far as the Java Language Specification is concerned, although both use the new keyword, Class Instance Creation Expressions and Array Creation Expressions are different forms of expression, each with its own rules. The description of Array Creation Expressions does not mention calling a constructor.
I don't think so because you can not derive a native array to overridethe constructor
You can use byte code manipulation to place the check where ever a new array is created.
Nope. I found this on the AspectJ mailing list: http://dev.eclipse.org/mhonarc/lists/aspectj-users/msg02975.html.
You probably ask about arrays for a reason, but if you can, why not switch to the collection classes. That will give you lots of opportunity to intercept and do validations.