2
ArrayList<StringBuilder> al = new ArrayList<>(
                              Arrays.asList(new StringBuilder[]{
                                  new StringBuilder("Oracle"), 
                                  new StringBuilder("Java"), 
                                  new StringBuilder("Sun"), 
                                  new StringBuilder("DataBase")}));

StringBuilder[] al2array = (StringBuilder[]) al.toArray();

If al.toArray() returns an Object[] which i know that its actually a StringBuilder[], then why cannot i cast it?

Jeroen Vannevel
  • 41,258
  • 21
  • 92
  • 157
Laz London
  • 247
  • 3
  • 9
  • 2
    Use the overloaded method `toArray(T[] a)` – Alexis C. Nov 27 '13 at 15:40
  • Possible duplicate of [make arrayList.toArray() return more specific types](http://stackoverflow.com/questions/5061640/make-arraylist-toarray-return-more-specific-types). See also: [Quick Java question: Casting an array of Objects into an array of my intended class](http://stackoverflow.com/questions/395030/quick-java-question-casting-an-array-of-objects-into-an-array-of-my-intended-cl). – Paul Bellora Nov 27 '13 at 15:42
  • Just to be clear - are you merely asking for an explanation of why this is the case, or is your question really asking how to do this properly? – Duncan Jones Nov 27 '13 at 15:47
  • Thank you all for your answers!! It made it clear that the type of the object reference (Object[]) which comes from the toArray() method, and the type of the object being referred to are the same (Object [] and cannot be StringBuilder[] or anything else). Thank you @Hot Licks for the example!! – Laz London Nov 27 '13 at 17:38

5 Answers5

3

Java has no way of knowing (at compile time) what objects are stored in an Object[]. Theoretically, it could contain Integers, Strings and GrumpyCats, which would make the cast to StirngBuilder[] wrong - so java simply does not allow it.

You could, however, use the overriden toArray(StringBuilder[]) to do this safely:

StringBuilder[] al2array = al.toArray(new StringBuilder[al.size]);
Mureinik
  • 252,575
  • 45
  • 248
  • 283
2

You most certainly can cast a variable typed as Object[] to one typed as StringBuilder[]. The compiler will not complain, and it will execute without error, IF the source reference does indeed reference a StringBuilder[].

public class ArrayCastTest {
    public static void main(String[] argv) {
        Object[] objArray;
        StringBuilder[] sbArray;
        objArray = getArray();
        sbArray = (StringBuilder[]) objArray;
        System.out.println(sbArray.toString());
    }

    public static Object[] getArray() {
        return new StringBuilder[5];
    }
}

This executes without error:

C:\JavaTools>javac ArrayCastTest.java

C:\JavaTools>java ArrayCastTest
[Ljava.lang.StringBuilder;@76f4da6d

C:\JavaTools>

The important thing to understand is that cast is "overloaded" -- it transforms simple values (like int to char) but it does not transform object references -- it only changes the declared type of the reference. The problem is that ArrayList.toArray() returns an Object[]. To get your Object[] into a StringBuilder[] use System.arraycopy.

Hot Licks
  • 44,830
  • 15
  • 88
  • 146
1

Try this ie use the the overloaded method toArray(T[] a) since toArray returns an Object[] and you cannot downcast it to StringBuilder[]. The reason is Java does not allow it ie casting it like that ie, an array of Object is created by toArray(), and you can't make Object into DataObject just by casting it.

So you can use the overriden toArray(StringBuilder[]) like this:-

StringBuilder[] al2array =al.toArray(new StringBuilder[al.size()]);

instead of

StringBuilder[] al2array = (StringBuilder[]) al.toArray();
Rahul Tripathi
  • 152,732
  • 28
  • 233
  • 299
0

do like this

StringBuilder[] al2array =al.toArray(new StringBuilder[al.size()]);
Prabhakaran Ramaswamy
  • 23,910
  • 10
  • 51
  • 62
0

If al.toArray() returns an Object[] which i know that its actually a StringBuilder[], then why cannot i cast it?

Because it is not actually a StringBuilder[] - it is an Object[] containing (only) StringBuilder instances. Consider this:

Object[] oa = new Object[2];
oa[0] = new StringBuilder();
oa[1] = new StringBuilder();

Would you expect to be able to cast oa to StringBuilder[]? If you did:

StringBuilder[] sba = (StringBuilder []) oa;

What would happen if you then did:

oa[0] = "";   // oa[0] now contains a String; what does sba[0] contain?
davmac
  • 18,558
  • 1
  • 32
  • 55
  • **Because it is not actually a StringBuilder[] - it is an Object[] containing (only) StringBuilder instances.** This is the point, thank u!!. So the returned Object is not an Object[] type StringBuilder[] Object :) – Laz London Nov 27 '13 at 17:42