2

As the Jon's answer of this post has said, if compiler allows this cast (shown below), to add some other objects later can be a bad thing for program.

    ArrayList<String> temList = new ArrayList<String>();
    ArrayList<Object> obList = (ArrayList<Object>)temList;//compile error
    //obList.add(1); --bad

But what confuses me is why in the same situation, array has the different behaviours.

    String[] strings = new String[10];
    Object[] temp = (Object[])strings;//nothing happens

So could anyone explain what is the difference here and why java make such design? Thanks.

Edit: one similar question

Community
  • 1
  • 1
Tony
  • 5,972
  • 2
  • 39
  • 58

2 Answers2

1

Arrays are not 100% Objects, they are mundane objects. But ArrayList a 100% object.

If you try to assign an Integer to the temp array it will throw an ArrayStoreException.

So casting arrays is fine.

But Casting ArrayList to a Super Object where the Underlying ArrayList implementation can only hold a String (Sub Class) will cause problems during the Runtime.

Thanks to Generics the compiler can identify this before it happens and can show a compiler error. This is a good design if not the program will fail during runtime.

Prior to Java 1.5 Generics

List list = new ArrayList();
list.add(1);
list.add("One");
list.add(100l);

Was legal the coders had to do a lot of instanceof checks. Where they failed to check the program crashed during runtime.

shazin
  • 21,379
  • 3
  • 54
  • 71
  • Semi-unrelated question, why is it that people attribute Javascript's ability to store different kind of objects in an array a positive? It basically functions as an Object[] in Java, just without the casting. I believe it to be a coding hazard. – EpicPandaForce Jun 27 '14 at 08:13
  • @shazin Sorry, but what is the mundane object mean? Any example or references? And why array doesn't make this kind of cast a compiler error. Thanks. – Tony Jun 27 '14 at 08:33
  • @Tony it means it is not a 100% object because it doesn't have functions on anything but it has a fields like 'length'. It is more than a premitive variable but less than a fully fledged object. – shazin Jun 27 '14 at 08:50
  • @shazin Um, arrays extend `Object`. Therefore, they are "fully fledged objects". No question about it. – awksp Jun 27 '14 at 14:45
0

Arrays were designed to allow covariant assignments if an array's component type is assignable to the assigned array's component type. Type checks are rather done at runtime by the JVM where an ArrayStoreException is thrown in case a value is attempted to be stored in an incompatible array. Used right, this allowed to express covariant types for array's what is often handy.

However, this language feature can lead to diffuse runtime exceptions what Sun did not want to repeat for generic type assignments which were introduced with Java 5. Instead, Sun wanted to uncover such invalid use at compile time. This seemed especially important as generics introduced a more complex type system component than array types such that runtime errors similar to the ArrayStoreException would surely have become more common if Sun had decided differently. Instead, for generics the issues of co- and contravariance were addressed by wildcards which allow to uncover type errors at compile time instead of runtime.

Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192