• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Liutauras Vilda
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • fred rosenberger
  • salvin francis
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Carey Brown

Why is a Cat[] instance is assignable to an Animal[] reference?

 
Ranch Hand
Posts: 209
13
VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Assuming Cat extends Animal, the following is legal:

and, if I ask if a Cat[] instance is an instance of Animal[]:

the result is true.

So, I was expecting that if I were to follow the inheritance tree of Cat[] back to Object, I would find it descendant from Animal[], something like:
Cat[] -> Animal[] -> Object
but in fact, that's not the case:


output:


So how come the assignment of a Cat[] instance to an Animal[] reference is even possible?
 
author
Posts: 23879
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Richard Hayward wrote:
So how come the assignment of a Cat[] instance to an Animal[] reference is even possible?



If I had to speculate ... I would say that it was a poor design decision. While I agree that it is actually nice to have a parallel inheritance hierarchy for arrays, technically, it doesn't actually behave as such. An Animal[] instance can hold any Animal element, such as Dog, Horse, Bird, etc., so by allowing the assignment, you end up with an Animal array reference that points to something that only allows Cat instances.

Henry  
 
Richard Hayward
Ranch Hand
Posts: 209
13
VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Henry Wong wrote:
If I had to speculate ... I would say that it was a poor design decision.



Thanks Henry.

I was wondering if there was some more satisfying explanation other than it simply being an anomaly of the language.
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wikipedia has an explanation (which uses the same example as you do here): Covariance and contravariance

It is indeed a poor design decision in the Java programming language that arrays are regarded as being covariant. They should have been invariant.
 
Ranch Hand
Posts: 231
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think that the OP is puzzled as to why the direct superclass of Cat[] is Object when Cat[] is assignable to Animal[].

I think that the direct superclass of Cat[] would still be Object even if arrays were invariant and this might have something to do with the fact that an array is not implemented as a regular class. The JLS says that an array type is not a class.

The JLS says that the supertype relation for array types is not the same as the superclass relation but this does not matter in practice.

"JLS" wrote: The supertype relation for array types is not the same as the superclass relation. The direct supertype of Integer[] is Number[] according to §4.10.3, but the direct superclass of Integer[] is Object according to the Class object for Integer[] (§10.8). This does not matter in practice, because Object is also a supertype of all array types.


 
Sheriff
Posts: 7647
522
Mac OS X VI Editor BSD Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Daniel Cox wrote:... direct superclass of Cat[] is Object when Cat[] is assignable to Animal[].

It isn't. Java doesn't support multiple inheritance. Only one top level class directly inherit behavior from Object, while others inherit only from their direct super classes.
 
Daniel Cox
Ranch Hand
Posts: 231
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Liutauras Vilda wrote:

Daniel Cox wrote:... direct superclass of Cat[] is Object when Cat[] is assignable to Animal[].

It isn't.


The JLS quote I referenced in my previous post says that "the direct superclass of Integer[] is Object". Are you saying that the direct superclass of Cat[] is not Object? Or are you saying that Cat[] is not assignable to Animal[]?
 
Liutauras Vilda
Sheriff
Posts: 7647
522
Mac OS X VI Editor BSD Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It seems you're right. I found a bit more readable part in JLS

JLS wrote:4.3.2 The Class Object
The class Object is a superclass (§8.1.4) of all other classes.
All class and array types inherit (§8.4.8) the methods of class Object

I didn't know that even in explicit "extends" case it directly inherits also from object. But that probably doesn't really matter in practice to know.

Even tho, could be a bit confusing here, yes, object is a superclass of all other classes, we know that, but doesn't say if it is direct superclass. Not sure after all.
 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Remember that the first version of Java didn't include generics.  My speculation is that this was a compromise to be able to write general purpose array handling methods.

If you couldn't assign all arrays to an Object[] reference, then how (in the absence of generics) would you write a method like Array.sort that can sort anything you want without having a different method for every class?  
 
This is my favorite tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
    Bookmark Topic Watch Topic
  • New Topic