Array casting problem

O

O.B.

Why does the cast in the following code snippet fail?


private InternetAddress[] getAddressAsArray(String address) {
List emails = new LinkedList();
String[] addresses = address.split(",");
for (int i = 0; i < addresses.length; i++) {
String tempAddress = addresses.trim();
if ( 0 < tempAddress.length()) {
try {
emails.add(new InternetAddress(tempAddress));
} catch (AddressException e) {
logger.error(e);
}
}
}
InternetAddress[] blah = null;;
try {
// Why is this causing a class cast exception?
blah = (InternetAddress[])emails.toArray();
} catch (RuntimeException e) {
logger.error(e);
}
return blah;
}
 
K

klynn47

You need to use the version of toArray that specifies the runtime type
of the array returned.

blah = (InternetAddress[])emails.toArray(new InternetAddress[0]);
 
E

Eric Sosman

O.B. wrote On 12/13/05 16:36,:
Why does the cast in the following code snippet fail?


private InternetAddress[] getAddressAsArray(String address) {
List emails = new LinkedList();
String[] addresses = address.split(",");
for (int i = 0; i < addresses.length; i++) {
String tempAddress = addresses.trim();
if ( 0 < tempAddress.length()) {
try {
emails.add(new InternetAddress(tempAddress));
} catch (AddressException e) {
logger.error(e);
}
}
}
InternetAddress[] blah = null;;
try {
// Why is this causing a class cast exception?
blah = (InternetAddress[])emails.toArray();
} catch (RuntimeException e) {
logger.error(e);
}
return blah;
}


Because an array of Objects is not an array of
InternetAddresses, even if each individual element
of the Object array refers to an InternetAddress.
Use the other toArray() method of List:

blah = (InternetAddress[])
emails.toArray(new InternetAddress[0]);
 
R

Roedy Green

blah = (InternetAddress[])emails.toArray(new InternetAddress[0]);

that needlessly creates an extra object and makes toArray go through
ugly means to create one the proper size.
 
D

Daniel Dyer

You need to use the version of toArray that specifies the runtime type
of the array returned.

blah = (InternetAddress[])emails.toArray(new InternetAddress[0]);

The docs say:

"If the list fits in the specified array, it is returned therein.
Otherwise, a new array is allocated with the runtime type of the specified
array and the size of this list."

So, since you know the size of the collection, it's better to do it this
way as you won't allocate two arrays:

blah = (InternetAddress[])emails.toArray(new
InternetAddress[emails.size()]);

Dan.
 
M

Mike Schilling

Roedy Green said:
blah = (InternetAddress[])emails.toArray(new InternetAddress[0]);

that needlessly creates an extra object and makes toArray go through
ugly means to create one the proper size.

Ugly? It does the same calculation the caller would make to create one of
the proper size. i.e. call emails.size()..

I'd probably use a static InternetAddress[0] to avoid creating a new one
each time (the cost of a zero-length array being negligible), but I admit
I'm lazy when it comes to micro-optimizations.
 
R

Roedy Green

Ugly? It does the same calculation the caller would make to create one of
the proper size. i.e. call emails.size()..

here is the code:

public <T> T[] toArray(T[] a) {
if (a.length < size)
a = (T[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), size);
int i = 0;
Object[] result = a;
for (Entry<E> e = header.next; e != header; e = e.next)
result[i++] = e.element;

if (a.length > size)
a[size] = null;

return a;
}

If you don't provide the array the proper size, you use reflection to
create the new array, vs plain new to create it if you do provide it.
 
M

Mike Schilling

Roedy Green said:
Ugly? It does the same calculation the caller would make to create one of
the proper size. i.e. call emails.size()..

here is the code:

public <T> T[] toArray(T[] a) {
if (a.length < size)
a = (T[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), size);
int i = 0;
Object[] result = a;
for (Entry<E> e = header.next; e != header; e = e.next)
result[i++] = e.element;

if (a.length > size)
a[size] = null;

return a;
}

If you don't provide the array the proper size, you use reflection to
create the new array, vs plain new to create it if you do provide it.

Thanks, I'd never looked at that code before, but now that you show it, it's
pretty obvious that that would be required.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top