8

The Java Language Specification says:

An object is a class instance or an array.

And it also says:

arrays [...] may be assigned to variables of type Object

But the part that confuses me is:

The class Object is a superclass of all other classes

If arrays may be assigned to variables of type Object, then it must mean that arrays can be Objects (not only behave as, but to be instead). Then it means that an array is a class instance, which does not seem to be consistent with the first quote (if it were, then why would it be listed as a different thing?).

How can all this fit together?

Aldan Creo
  • 686
  • 1
  • 5
  • 14
  • 2
    "*Then it means that an array is a class instance*" - No. The first quote clearly says "*An obejct is a class instance **or** an array*". If an array were a class instance, the sentence "*An obejct is a class instance.*" would be sufficient. – Turing85 Jan 16 '21 at 12:43
  • 1
    The English word object in the first sentence is referring to a generic object, ie. something material that may be perceived by the senses. The Object in the third sentence is referring to a specific Java class, Object. An array of Java class instances is still an array of objects, ie. material things. – Gilbert Le Blanc Jan 16 '21 at 12:45
  • 1
    Yes, but as an array *"may be assigned to variables of type Object"*, doesn't that imply that an array is not only an object, but an Object as well, making the sentence *"An object is a class instance"* sufficient? – Aldan Creo Jan 16 '21 at 12:48
  • This https://stackoverflow.com/questions/8546500/why-isnt-there-a-java-lang-array-class-if-a-java-array-is-an-object-shouldnt and https://www.geeksforgeeks.org/array-primitive-type-object-java/ might help you understand – dreamcrash Jan 16 '21 at 12:53
  • 1
    Does this answer your question? [Is an array an object in Java?](https://stackoverflow.com/questions/8781022/is-an-array-an-object-in-java) – Mats Jun Jan 16 '21 at 13:02
  • Unfortunately, all those links don't actually answer my question. They are only the source of my doubts. My point here is the one I wrote below: *if an array subsumes Object (because it is assignable to it), and an Object is a class instance, how can it be the case that an array is not a class instance?* – Aldan Creo Jan 16 '21 at 13:06
  • 1
    @AldánCreo where does the JLS state that "*an Object is a class instance[Period]*"? – Turing85 Jan 16 '21 at 13:08
  • @Turing85 Well, then... does that mean that an Object variable does not necessarily contain class instances that subsume Object? It would be quite counterintuitive. – Aldan Creo Jan 16 '21 at 13:11
  • 1
    @AldánCreo please take a look at [this comment of mine](https://stackoverflow.com/questions/65749745/are-java-arrays-class-instances?noredirect=1#comment116249487_65749745). In general, Java has very few edge-cases. Arrays and their relation to `Object` is one of them. – Turing85 Jan 16 '21 at 13:12
  • So I guess we could say this is basically an edge-case that stands in a threshold between *being represented as a class instance* (as an array has an associated Class class instance), and actually being it? – Aldan Creo Jan 16 '21 at 13:16
  • @AldánCreo had to delete my other comment. We can actually access `String[].class` as `String[]`'s "class". – Turing85 Jan 16 '21 at 13:20
  • Yes, indeed, that's why I guess we could say that an array *can be represented as a class instance*, but that it is not actually a true *class instance*. – Aldan Creo Jan 16 '21 at 13:27

5 Answers5

7

There is no contradiction. An array is also an Object, albeit a special kind of Object.
It is like saying: An bird is also an animal, albeit a special kind of animal.

You can convince yourself by compiling and running the following Java code.

    String[] arrayOfStrings = { "bla", "blah" };
    
    // examine the class hierarchy of the array 
    System.out.println("arrayOfStrings is of type "
            + arrayOfStrings.getClass().getSimpleName()
            + " which extends from "
            + arrayOfStrings.getClass().getSuperclass().getSimpleName());
    
    // assingning the array to a variable of type Object
    Object object = arrayOfStrings;

The output will be

arrayOfStrings is of type String[] which extends from Object
Thomas Fritsch
  • 9,639
  • 33
  • 37
  • 49
6

Arrays are special classes provided to you by Java itself. All of them inherit from common superclass Object. As they inherit from Object they of course can be used anywhere where Object is expected. Instances of arrays are indeed instances of those classes. One can even reference array classes as they do with other classes' literals:

    Class<int[]> intArrayClass = int[].class;

I see no conflict.

This can be useful https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html#jls-10.8

Vasily Liaskovsky
  • 2,248
  • 1
  • 17
  • 32
2

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!]

Aldan Creo
  • 686
  • 1
  • 5
  • 14
0

The class Object is a superclass of all other classes

All classes in Java extend Object. The class name is actually Object (proper name capitalized). It's why all classes have the method toString() and hashCode(), because they all inherited it from Object.class

An object is a class instance or an array.

An object (lowercase, not a proper name) is the instance generated by the new keyword. ie: File is a class and when you call new File() you just made a File object. I honestly think they should have called it a class instance. (clarification: I wish they never called an instance an object)

arrays [...] may be assigned to variables of type Object

Object[] is an array that can contain instances of type Object.

Object[] obj = new Object[100];

obj instanceof Object evaluates to true.

  • "*... File is an object...*" - I suspect you mean `File`? That is not an object, but a class (in some other languages this may be called a *type*). --- "*Object[] is an array that can contain instances of type Object.*" - I do not see the relevance of this statement wrt. to the question. – Turing85 Jan 16 '21 at 13:01
  • 1
    Yeah. I've been proofreading this. Even writing a clarification of this stuff is like playing Jenga with Rubix Cubes. –  Jan 16 '21 at 13:03
  • But, if an array subsumes Object (because it is assignable to it), and an Object is a class instance, how can it be the case that an array is not a class instance? I'm not speaking about the fact that arrays can contain instances of Object, I'm referring to arrays being not only objects, but instances of Object as well. – Aldan Creo Jan 16 '21 at 13:04
  • 1
    `Object[]` is not an array. It's a _type_ (of a variable that can hold a reference _to_ an array of `Object`s). – Gerold Broser Jan 16 '21 at 13:13
0

Your second link also says:

All methods of class Object may be invoked on an array.

So from a dev's POV, at least, it's an Object though there is no java.lang.Array (that is exposed to us) it has been instanced from.

A second indication is that arrays are also stored on the heap.

Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
  • "*... at least, it's an `Object` though there is no `java.lang.Array` (that is exposed to us) ...*" - What about, e.g., `String[].class`? – Turing85 Jan 16 '21 at 13:20
  • @Turing85 What about `System.out.println( String[].class );` → `class [Ljava.lang.String;`? Or what do you mean in detail? – Gerold Broser Jan 16 '21 at 13:26
  • I mean that there is a "class" for arrays exposed to us. – Turing85 Jan 16 '21 at 13:27
  • @Turing85 Yes, but it's not `java.lang.Array`. Isn't clear what I meant in the context "_there is no `java.lang.Array` (that is exposed to us)_"? – Gerold Broser Jan 16 '21 at 13:34
  • 1
    An `java.lang.Array` class would not work with the object-hierachy in Java. Reasoning: `class`-instances are, among other things, used to check assignment-compatibiliity and `java.lang.Array` loses the information of the contained type. Furthermore, generics would not really work since arrays are covariant, while generics are invariant. Thus, using the syntax `Object[].class`, `String[].class`, .... seems like a valid way to represent array-classes. – Turing85 Jan 16 '21 at 13:40