I was wondering about the implementation of length of a Java Array. I know that using arrayName.length gives us the number of elements in the array, but was wondering if this is a method / function or it is just a data member of Array?
I guess it must be a data member as we do not use parenthesis() when invoking it. But if it is a data member how/when is the value of this length assigned/computed?
According to the Java Language Specification (specifically §10.7 Array Members) it is a field:
The public final field length, which contains the number of components of the array (length may be positive or zero).
Internally the value is probably stored somewhere in the object header, but that is an implementation detail and depends on the concrete JVM implementation.
The HotSpot VM (the one in the popular Oracle (formerly Sun) JRE/JDK) stores the size in the object-header:
[...] arrays have a third header field, for the array size.
You're correct, length is a data member, not a method.
From the Arrays tutorial:
The length of an array is established when the array is created. After creation, its length is fixed.
If you have an array of a known type or is a subclass of Object[] you can cast the array first.
Object array = new ????[n];
Object[] array2 = (Object[]) array;
System.out.println(array2.length);
or
Object array = new char[n];
char[] array2 = (char[]) array;
System.out.println(array2.length);
However if you have no idea what type of array it is you can use Array.getLength(Object);
System.out.println(Array.getLength(new boolean[4]);
System.out.println(Array.getLength(new int[5]);
System.out.println(Array.getLength(new String[6]);
Yes, it should be a field. And I think this value is assigned when you create your array (you have to choose the length of array while creating, for example: int[] a = new int[5];).
I believe its just a property as you access it as a property.
String[] s = new String[]{"abc","def","ghi"}
System.out.println(s.length)
returns 3
if it was a method then you would call s.length() right?
From the JLS:
The array's length is available as a
final instance variable length
And:
Once an array object is created, its
length never changes. To make an array
variable refer to an array of
different length, a reference to a
different array must be assigned to
the variable.
And arrays are implemented in the JVM. You may want to look at the VM Spec for more info.
It is a public final field for the array type. You can refer to the document below:
http://java.sun.com/docs/books/jls/third_edition/html/arrays.html#10.7
Every array in java is considered as an object. The public final length is the data member which contains the number of components of the array (length may be positive or zero)
Java arrays, like C++ arrays, have the fixed length that after initializing it, you cannot change it. But, like class template vector - vector <T> - in C++ you can use Java class ArrayList that has many more utilities than Java arrays have.
Related
I'm learning about Java arrays and I read something along the lines of that Java arrays are actually objects. Does that mean that when I make an array, say int[] array = new int[10], the underlying mechanism is really just a class file that gets created with 10 instance variables of type int that I can access with array[(0-9)]? If so, how does it do that and how does it work? And what is the conceptual reason (if any) for the syntax to declare arrays the way it is (so I can remember the syntax rules easier)?
This is what I read in the textbook I am learning from:
Creating and Accessing Arrays
In Java, an array is a special kind of object, but it is often more
useful to think of an array as a collection of variables of the same
type. For example, an array consisting of a collection of seven
variables of type double can be created as follows:
double[] temperature = new double[7];
This is like declaring the following seven strangely named variables
to have the type double:
temperature[0], temperature[1], temperature[2], temperature[3],
temperature[4], temperature[5], temperature[6]
Arrays in Java are objects, but they are not instances of any class. There are no array classes -see
On the object types - section 4.3.1:
An object is a class instance or an array.
Array objects are similar to classes with a number of variables, but an array of 10 doubles is not a class. It's more like, "array of doubles" is one single type, and the number of instance variables is stored within the object itself, in the array's length field.
On arrays - section 10:
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).
An array object contains a number of variables. The number of variables may be zero, in which case the array is said to be empty. The variables contained in an array have no names; instead they are referenced by array access expressions that use non-negative integer index values. These variables are called the components of the array.
How arrays are implemented in a JVM is another matter. In OpenJDK, the memory layout for array objects includes a pointer to an "ArrayKlass" which is an internal representation for the array type. The size of the array is included within the array object, and the array objects themselves can have an arbitrary size. This is different from objects that are class instances: class instances are always the same size.
in the code where you allocate an array:
int myInts = new int[20];
The JVM will allocate a block the size of 20 times the size of an integer (4 bytes) in the heap. The array is accessed / indexed using the index offset times the primative object size (again in this case, 4 bytes)
Also, I believe that array indexing is built directly into Java byte codes.
--- Edit ---
On array indexing being built in: If you look here, you can confirm the aaload JBC command / retrieve from an array: https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
What does this syntax do, with square brackets around the number?
new Integer[0];
I've found it in a codebase I'm maintaining but I can't find any documentation on it. It is used like this:
Set<Form> forms = getForms();
List<Form> formsList = Arrays.asList(forms.toArray(new Form[0]))
It allocates an array with length zero; e.g. new Integer[0] creates a zero length array of Integer objects.
Why would you do that?
Well look at the javadocs for the form.toArray(T[]) method. Assuming that form is some subtype of Collection they are here.
The purpose of the toArray method is to copy the elements of the target collection (e.g. your form) into an array:
If the argument array is large enough to hold all elements, they are copied into that array. The result will be the argument array.
If the argument array is too small, a new array is allocated with the same type as the argument array and a length that is (just) enough to hold the elements. The elements are then copied into the new array, and it is returned as the result.
So what the code is actually doing is copying the elements of form to an Integer[] of the right size, and then wrapping the array to give a (fixed sized) List<Integer>. This can then be passed to some other code without worrying that that code might alter the original form collection.
Unlike traditional array which store values like string, integer, Boolean, etc. array of objects stores objects. The array elements store the location of reference variables of the object
Syntax:
Class obj[]= new Class[array_length]
According to this site the syntax for creating a Java object is:
<JavaType> <variable> = new <JavaObject>();
Though you don't use any parantheses when creating an Array object and instead type brackets which contains the length of each dimension.
Example:
String[][] stringMatrix = new String[5][10];
What I am wondering is if this syntax is specifically and only for creating an Array object or I can make a custom class whose objects are created in a different way then usual
new <JavaObject>();
statement.
new keyword is used to allocate memory for the specific type, which is followed by new keyword.
MyClass obj = new MyClass();
Above line will create an object (allocate memory) for MyClass and initialize member variable by invoking default constructor.
But, below line of code will only allocate memory and initialize each element of array with default value null.
MyClass[][] objMatrix = new MyClass[5][10];
So, we are just declaring an array of size 5x10(allocating memory), but each element in array need some object reference (since, currently they have null reference). So, for that reason, you need to initialize each objMatrix array element by creating object of MyClass and assigning them to each element.
objMatrix[0][0] = new MyClass();
It is specifically for creating arrays. You're stuck with parentheses for your classes.
You can not create a custom class that changes the way the new operator works. However, there are some special cases where an object can be created without the usual new operator.
E.g.
String[] array = { "foo", "bar", "baz" };
Integer value = 42;
demonstrating that you can create arrays without the new keyword in a variable initializer, use String objects using literals and autobox primitive values to their object counterpart without the usual new syntax, but of course, this is not possible with custom types.
Another possibility to create objects without the new operator is deserializing them, which also works for custom types if they are Serializable.
Starting with Java 8, you can use constructor references if you have an appropriate context, e.g.
BigDecimal[] array = new BigDecimal[20];
Arrays.setAll(array, BigDecimal::new);
System.out.println(Arrays.toString(array));
Here, BigDecimal::new is a reference to a constructor of BigDecimal and it is implied from the context, i.e. Arrays.setAll that the function must be able to consume an int value, as the setAll method will evaluate it for every array element, passing the array index, so we initialize the array with ascending numbers in this example.
Another example would be
BigDecimal[] array = Stream.of("1.23", "4.56", "7.89")
.map(BigDecimal::new)
.toArray(BigDecimal[]::new);
System.out.println(Arrays.toString(array));
where it is implied from the context that the constructor used in the .map(BigDecimal::new) step must consume a String, as it will be evaluated for every stream element, ending up at a different constructor than in the first example.
BigDecimal is an ordinary class and these examples would work with a custom class as well, if it has matching constructors.
I was trying to allocate an Integer array for 100 items, why this declaration isn't valid in Java?
Integer[100] intArr1; ----- (1)
Whereas this is valid:
Integer[] intArr; ----- (2)
As (2) is valid, how much memory does it occupy? Can anyone help to explain a bit.
There are some questions in SO which resemble my question, however they are not the same, and I did look in SO before asking this question.
The first one isn't valid because that's not proper Java syntax.
The second one occupies 0 memory, as you haven't created an array. Only a reference to an array, with the reference being null.
You need a new Integer[100] there to actually create the array object.
You are mixing two different things.
One thing is the type of variable. In your case, you want to say "the type of variable intArr is array of Integers", which is this code Integer[] intArr;
In variable, which type is array of Integers you can put any array of Integers you like, no matter the size, therefore you cannot pre-defined it.
The second thing is assign to a variable.
Integer[] intArr = new Integer[10];
To initialise an array with 100 items you write:
Integer intArr1[] = new Integer[100];
Your second line of code just declares a variable, there is no size declared.
When you declare an array, you don't give it a length. You only give it a length when you initialise it.
This is just a declaration:
int[] myArray;
If you want to initialize it with an array of length 100, you do this:
myArray = new int[100];
An uninitialised array is null by default, or inaccessible if it is in a local scope.
If I have an int array structured like this:
private int[][] map = new int[400][400];
And I try to retrieve
map[100][200]
And that element isn't initialized, will i get a compiler/runtime error or will it return null? And is there any function to check if a given element/index exists/has been set?
As your array declaration is of a primitive type you won't get any compiler or runtime errors - the default value of 0 will be returned.
If your array had been an array of Objects, then the array would hold null for any element not specifically assigned.
I won't return null because int is a primitive type. It will return the default int value, which is 0.
There is no way of knowing if any element has been set, short of keeping a separate boolean array.
In Java, only reference variables are initialized to null. Primitives are guaranteed to return appropriate default values. For ints, this value is 0.
No.
Your array elements are only big enough to hold ints, in this case. There is no place to store the information about if the element "exists". It has been allocated, thus it exists. In Java, newly allocated int arrays will be initialized to all elements zero.
You can use checkstyle, pmd, and findbugs on your source (findbugs on the binary) and they will tell you things like this.
Unfortunately it doesn't look like they catch this particular problem (which makes sense the the array is guaranteed to have each member set to 0, null, or false).
The use of those tools can will catch instance and class members (that are not arrays) that are being used before being given a value though (similar sort of issue).
Bit of a dead topic but I found it by accident so I'm gonna place my piece of wisdom (or whatever :P). You could use Arrays.Fill to fill your array when it's created with an invalid value like -1. Then you can easily do an if x<0 to check if YOU have initialized that specific array position or not. Just an idea...