Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.ArrayStoreException: when assigning value with incorrect type to Object[] array [duplicate]

Tags:

java

I come from a C background. It doesn't make sense to me that I can't add an Object to a Object[] in foo().

I would expect the code in function foo to work at runtime but fail in main() when I attempt to do strings[0].toLowerCase(); because the object in strings[0] is not a String but is actually a StringBuilder which doesn't have a toLowerCase(). At the end of the day, I am storing a pointer into an array of pointers and the line objects[0] = other should not be invalid. It is clear my understanding of java is wrong (but I an fairly new at the moment).

class Main {

    static void foo(Object[] objects, Object other) {
        objects[0] = other;
    }
    public static void main(String[] args) {
        String[] strings = { "stringValue" };
        foo(strings, new StringBuilder());
    }
}

EDIT: Thanks all for the answer. I googled "java covariance of arrays" thanks to @Andy Turner and came across this which discusses this behaviour. The trick is that the compiler and runtime treat the code very differently. Compiler is fine with the code, runtime isn't.

like image 249
s5s Avatar asked Jun 10 '18 15:06

s5s


2 Answers

From the documentation of ArrayStoreException:

Thrown to indicate that an attempt has been made to store the wrong type of object into an array of objects. For example, the following code generates an ArrayStoreException:

Object x[] = new String[3];
x[0] = new Integer(0);

Just because you're passing a String[] into a method that expects an Object[] doesn't mean that it's actually an Object[]. Because you create a String[], you can only add instances of String to it, and you're trying to add a StringBuilder, which doesn't make sense.

Notice how it does not throw an exception if you change the type of String[] to Object[]:

public static void main(String[] args) {
    Object[] strings = { "stringValue" };
    foo(strings, new StringBuilder()); // Perfectly fine
}
like image 157
Jacob G. Avatar answered Sep 17 '22 01:09

Jacob G.


It is evaluated at runtime that your String Array is in fact trying to assign a different type. You would an ArrayStoreException, which clearly says that

Thrown to indicate that an attempt has been made to store the wrong type of object into an array of objects. For example, the following code generates an ArrayStoreException:

Object x[] = new String[3];
 x[0] = new Integer(0);

It is not generally a good practice to accept Object types as parameters or even return values of methods/functions. They could be polymorphic interfaces, but Object is at the highest levels of abstraction, and is not ideal for this purpose.

like image 39
Sid Avatar answered Sep 20 '22 01:09

Sid