Is an Array an Object in Java

Is an array an object in Java?

Yes.

The Java Language Specification section 4.3.1 starts off with:

An object is a class instance or an array.

Are Java arrays class instances?

Yes... and no. It is true, indeed, that new Object[100] instanceof Objecttrue, but this is missing the true nature of arrays in Java. Arrays are objects (lowercase), but not Objects (capitalized). Being objects, for example, you have to use the new operator to allocate space for them.

However, the Java Language Specification is right to say that "An object is a class instance or an array", because arrays are fundamentally different from a regular Object. They are inherited from languages such as C++, that were much more deeply rooted in the low-level architecture of computers.

"arrays [...] may be assigned to variables of type Object" only because Java provides an interface for us, programmers, to refer to arrays as Objects. In fact, the JLS says:

All methods of class Object may be invoked on an array

Which of course is true, but it does not logically imply they are Objects. Arrays are not true Objects; therefore, they are not true class instances, and therefore the sentence "The class Object is a superclass of all other classes" doesn't apply here.

All in all, Java is not a pure Object-Oriented programming language (primitives are not objects, for example, but they are nonetheless present in Java). And arrays are a language feature that Java includes that behave as if they were class instances of the Object class, but are not actually class instances of it.

[This is my attempt at summarising the main points made here. Thanks a lot to all of you for your ideas, and feel free to add more!]

Is int[] an object?

An array in Java is a subclass of Object, therefore it's an object type - even if it contains primitive types. You can check this:

int[] x = new int[5];
if (x instanceof Object)
System.out.println("It's an Object!");

Objects in array in Java

There is a difference between declaration and initialization.

Dog[] pets declares that the variable pets is an array of Dogs
pets = new Dog[7] initializes the variable pets, it assigns it a value. The value is an array of size 7 full of null references.

It is the same for primitives :

int i; //declaration
i = 5; //initialization

As well as you can write

int i = 5;

you can write

Dog[] pets = new Dog[7];

In this case, you do the declaration and initialization on the same line.

Why are arrays Objects, but can not be used as a base class?

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).

If an array of Object is an Object, why is an array of String not a String

new String[]{"s","s"} is of type String[], not String. T[] is not a subclass of T (unless T happens to be Object).

Object[] is a subtype of Object, which is why the first one works. In fact, all array types are subtype of Object, including, perhaps surprisingly, arrays of primitives, like int[], even though int is not an Object (*).

You could write the first one using more specific types:

Object[] c = new Object[] {1,2,"22" };

You can write the second as any of the following:

String[] s1 = new String[]{"s","s"};
Object[] s2 = new String[]{"s","s"};
Object s3 = new String[]{"s","s"};

Incidentally, s2 demonstrates that arrays in Java are covariant. This is problematic, since you can legally write:

s2[0] = new Object();

which would fail at runtime with an ArrayStoreException, since you can't store Object references in a String[].

This is one of the reasons why authors like Josh Bloch give the advice "Prefer lists to arrays" (see Effective Java 2nd Ed Item 25), since Java collections like List are not covariant, and so don't suffer the same issue.


(*) Just to add to the confusion, primitive arrays are not subtypes of Object[], as primitives are not subtypes of Object. For example, it would be a compile-time error to write:

Object[] illegal = new int[5];

Is an array a primitive type or an object (or something else entirely)?

There is a class for every array type, so there's a class for int[], there's a class for Foo[]. These classes are created by JVM. You can access them by int[].class, Foo[].class. The direct super class of these classes are Object.class

public static void main(String[] args)
{
test(int[].class);
test(String[].class);
}

static void test(Class clazz)
{
System.out.println(clazz.getName());
System.out.println(clazz.getSuperclass());
for(Class face : clazz.getInterfaces())
System.out.println(face);
}

There's also a compile-time subtyping rule, if A is subtype of B, A[] is subtype of B[].

Object type in Java and referencing arrays

My understanding is that arrays are objects in Java, and therefore a subclass of the Object type. My further understanding is that a 2-dim array is implemented as an array of references to arrays.

This is all correct and explains why you can do the assignment

a[0] = b;

without any complaints from the compiler.

Therefore I don't understand why my a[0][0] does not produce bar in the code above.

Okay, let's take a look at the types in this expression:

  • a is a Object[] -- that is an array of Objects
  • a[0] is an Object
  • a[0][0] -- Now you are trying to use an array subscript on an Object. The compiler does not know that the Object is in fact an array, so it complains.


Related Topics



Leave a reply



Submit