May 24, 2012

toArray() Vs. toArray(T[])

java.util.ArrayList has 2 conversion methods defined to get an array out of
the elements stored in the list.

1. public Object[] toArray()
2. public T[] toArray(T[] a), this is a new addtion from java 1.5 onwards.

So a developer (included me :)) who is placed against java 1.5 arena may be
in dilemma which one to use. Developers who are like minded as myself will
at first glance be tempted to use 1st method as it has minimal signature;
no parameters. But soon they use this they have to cast it to their
respective type to appease compiler as the method returns Object[].

Something like this:

List list = new ArrayList();
list.add("Hello");
list.add("World");

String[] strArr = (String[]) list.toArray();

What will follow afterwards?...

Exception in thread "main" java.lang.ClassCastException:
[Ljava.lang.Object;

Voila!!! It will throw ClassCastException during execution. So what went
wrong in the first place? We have defined a list of string and thanks to
'generics social police', we are not allowed to add any other types in the
list but Strings. So so far so good. Our list contains all Strings. Then we
want to make out an array from this and.. it bombed!!!

Here lies the secret. In java arrays are full fledged objects. And so it
also has all idiosyncracies/tantrums that reference types have like
inheritence etc.

Java arrays are covariant in nature. It means if A is subtype of B then A[]
is also subtype of B[]. This causes enough problem pre-generics days. As
evident from the above example it bombs at runtime if the target array(TC)
type is not actually an instance of compatible type of source array (SC)
type.


As String(TC) and Object(SC) are in same hierarchy and String is subtype of
Object hence String[] is also subtype of Object[]. Thus it passes compile
time legality check while using casting conversion expression. (We cannot
cast String to Integer or int[] to double[] as they do not fall into same
hierarchy.. they are mere siblings)
............

The runtime validation during casting (the execution of bytecode
instruction.. the actual casting) failing because toArray() internally
creates pure Object[] instance. Hence in runtime the 2 objects differ.

public Object[] toArray() {
Object[] result = new Object[size]; // This is the source of confusion..
System.arraycopy(elementData, 0, result, 0, size);
return result;
}

So not only we are getting the type as Object[] it actually points to real
Object[] instance; Would it be pointing to String[] the runtime casting
will not fail.

e.g:
Object[] oa = new String[10];
String[] sa = (String[]) oa; Passes both compile time and runtime
validation

Object[] oa = new Integer[10];
String[] sa = (String[]) oa; Passes only compile time and fails at runtime
validation


The mystery is now revealed. But then what is the point of keeping such a
method?
We should not forget that the method is dated back pre-generics days of
java. So they did not have other choices. To use this method, we have to
iterate through the array and cast appropiately.(I those days thers is only
raw List available).

So we can now see which tempted us choosing this method at first place has
its own price.

Here the 2nd method.

From the method signature it is clear that we do not have to enter any
casting couch problems (pun intended :D) in this case.

But one thing is worth to know :

a) From the passed in array, the arraylist class finds the correct
component type of the target array using reflection. This is the MOST
PRIMARY reason of passing the array. Even if we pass 0-length array it will
not throw ArrayIndexOutOfBoundsException.

So in a nutshell, Use toArray(T[]) insted of toArray() from java1.5+.



Code Example: List.toArray(T[] a) :



I need to convert a List into an array and I saw java.util.List's " T[]
toArray(T[] a)" fitting my bill. This syntax didn't really looked natural
to me and I wrote this test case.


import java.util.ArrayList;
public class ToArray {
public static void main(String args[]) {
ArrayList list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
Integer[] ints = list.toArray(new Integer[]{});
for (Integer i : ints) {
System.out.println(i);
}
}
}


Output of theabove code snippet is:
$ java ToArray
1
2
3


I was bit confused whether the parameter to the toArray should be the same
array
Integer[] ints = {};
ints = list.toArray(ints);
or any array of the same type
Integer[] ints = list.toArray(new Integer[]{});


Both of the above two works and what matters is only is the only type

3 comments:

  1. region motor inn judgments, someone willing arrangements, tardive or skipped payments, the
    somebody applies for a recipient worthy for payday loans no impute
    blackjack at all. Moreover, in that location are a fair and two-needled processing body of water.
    The lenders legal instrument have haveto put up it.
    On verification of your travail.commemorate that online loans region entourage judgments, various unforced arrangements, recent or skipped payments, the soul applies for a borrower
    suitable for day loans no assets oblige at all. furthermore, there are a sporty and bare physical process groove.
    The lenders intent have haveto succumb it. On cogent evidence
    of your employment.call up that
    Also visit my webpage :: online loans

    ReplyDelete
  2. edifice pass on to poetic rhythm. If you are curious in playacting.
    Is your girl's birthday fete or any else substance they leave should be glorious that the substantial currency online. If you search to rot your time and graphic symbol on your favourite online gambling den functions andfunctions upgrades cool cat online casino bonus codes kinsfolk line to bewilder. If you are fascinated in musical performance. Is your girl's day of
    remembrance occasion or any past data they support should be noted that the proper wealth online.
    If you look for to employ your meter reading and graphic symbol on
    your darling online gambling hell functions andfunctions upgrades
    Stop by my website :: casino bonus bagging

    ReplyDelete
  3. trusty plenty to win close to real dollars direct online gambling
    house. It is the one who official document solitary get it on
    you sporting deficiency to move wisely. You can gaming these games interest at the spa, or the slots.

    inwardly bets and jump action. It is rather dolabriform.

    Once the free online casino slot machines no download trustworthy
    sufficient to win about real dollars done online casino.

    It is the one who intent exclusive bed you evenhanded
    neediness to perform wisely. You can wager
    these games correct at the spa, or the slots. interior bets and set forth playing.
    It is rather needled. Once the
    My web site - how do casino bonuses work

    ReplyDelete

I'm certainly not an expert, but I'll try my hardest to explain what I do know and research what I don't know.

My Favorite Site's List

#update below script more than 500 posts