9

I think I'm missing something basic here. Any explanation or pointers to previously asked questions will be very helpful.

import java.util.Arrays;
import java.util.List;

public class St {

    public static void bla(Object[] gaga) {
            gaga[0] = new Date(); // throws ArrayStoreException
        System.out.println(gaga[0]);
    }

    public static void bla(List<Object> gaga) {
        System.out.println(gaga.get(0));
    }

    public static void main(String[] args) {
            String[] nana = { "bla" };
        bla(nana); // Works fine

        List<String> bla1 = Arrays.asList(args);
        bla(bla1); // Wont compile

            System.out.println(new String[0] instanceof Object[]); // prints true
            System.out.println(nana.getClass().getSuperclass().getSimpleName()); // prints Object
    }

}

So, it seems like a List<String> is not a subclass of a List<Object> but a String[] is a subclass of Object[].

Is this a valid assumption? If so, why? If not, why?

Thanks

5 Answers 5

11

Java arrays are covariant, i.e. they allow Object[] foo = new String[2];. But this doesn't mean they are subclasses. String[] is a subclass of Object (although instanceof returns true, String[].class.getSuperclass() returns Object)

Sign up to request clarification or add additional context in comments.

3 Comments

From @maerics comment below -- the new String[0] instanceof Object[] returns true. So, String[] is a type of Object and a type of Object[] and a type of CharSequence[] etc. Correct?
@Kal that appears to be a special case to cover the covariance. See my update
String[] >1 Object seems to be a bug, I cannot get getSuperClass to return an Array for any other type either. But java.sun.com/docs/books/jls/third_edition/html/… seems to say that is what it should be
6

Yes, your assumption is valid. As said by @Bozho arrays are covariant, whereas generic collections (such as generic List) are not covariant.

Covariance in arrays is risky:

String[] strings = new String[] { "a", "b" }
Object[] objects = strings;
objects[0] = new Date();  // <-- Runtime error here 
String s = strings[0];
s.substring(5, 3);        // ????!! s is not a String 

The third line fires a runtime exception. If it weren't firing this exception then you could get a String variable, s, that references a value that is not a String (nor a subtype thereof): a Date.

1 Comment

Thanks .. I have never seen the ArrayStoreException before.
4
(new String[0] instanceof Object[]) // => true

Comments

3

You are correct. Array types are covariant in Java by design, but a Foo<Sub> is-not-a Foo<Super>.

Comments

2

String[] is a subclass of Object[]

Correct, see 4.10.3 Subtyping among Array Types:

If S and T are both reference types, then S[] >1 T[] iff S >1 T.

Since String >1 Object so String[] >1 Object[]

That is, String[] is a direct subtype of Object[]

Object >1 Object[]

Therefor Object > String[]; String[] is a (indirect?) subtype of Object

No such relationship exists for generics, so List<String> > List<Object> is not true.

Now, consider the following simple example:

import java.util.*;

class G {
    interface I {
    void f();
    }
    class C implements I {
    public void f() {}
    }

    void allF(List<I> li) {
    for (I i : li) { i.f(); }
    }

    void x(List<C> lc) {
    allF(lc);
    }
}

It does not compile, because x is invoking allF with a List<C> which is not a List<I>. To be able to use List<C> the signature has to change slightly:

void allF(List<? extends I> li) {

Now it compiles. Informally, li is a List of some type that extends/implements I. So List<C> is assignable to List<? extends I>. What you can do with such a list is limited. Essentially, you can read/access it but cannot write/modify it.

2 Comments

Umm ... subtype and subclass mean different things.
@StephenC, for classes subtyping is same as subclassing, if I am reading 4.10.2. I guess the correct response would be "Arrays are not classes so they cannot have subclass relationship but String[] is a sybtype of Object[]". Is that what you are hinting?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.