Generics in Java 1.5 ( or is it java 5.0 ?... I always haveconfusion)

V

Vikram

Hi,
Looking at the signature of the following method in
java.util.List

public interface List<E> extends Collection<E> {
.........
........
......

<T> T[] toArray(T[] a);
}

I wrote a small program as below:

ArrayList<String> c = new ArrayList<String>();
c.add("Vikram");
c.add("Pyati");
Integer[] i = new Integer[20];
c.toArray(i);

This did not give me a compilation error, though it fails at runtime
giving java.lang.ArrayStoreException, which is perfect.

My question is , why did the above mentioned method be declared as
<E> E[] toArray(E[] a);
which will force the method to take only the array of formal type ( in
this case a String[] ) at the compile time
 
R

Roland de Ruiter

Hi,
Looking at the signature of the following method in
java.util.List

public interface List<E> extends Collection<E> {
........
.......
.....

<T> T[] toArray(T[] a);
}

I wrote a small program as below:

ArrayList<String> c = new ArrayList<String>();
c.add("Vikram");
c.add("Pyati");
Integer[] i = new Integer[20];
c.toArray(i);

This did not give me a compilation error, though it fails at runtime
giving java.lang.ArrayStoreException, which is perfect.

My question is , why did the above mentioned method be declared as
<E> E[] toArray(E[] a);

You probably mean
E[] toArray(E[] a);
without the formal type parameter. Now E refers to the type parameter E
of class List.
which will force the method to take only the array of formal type ( in
this case a String[] ) at the compile time

In that case you could only convert the list to an array of E, and not
to an array of a superclass / interface of E.

There may be cases where it's useful to convert a list to an array of
Objects. With your proposal that's not possible (it would generating a
compile time error).

Modified example:

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class ToArray {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("Vikram");
list.add("Pyati");

// The following is OK
Object[] arrO = new Object[list.size()];
Object[] resArrO = list.toArray(arrO);
System.out.println(Arrays.deepToString(resArrO));

// The following is OK; String implements Serializable
Serializable[] arrS = new Serializable[list.size()];
Serializable[] resArrS = list.toArray(arrS);
System.out.println(Arrays.deepToString(resArrS));

// The following is OK at compile time, but toArray causes an
// ArrayStoreException at runtime
Integer[] arrI = new Integer[list.size()];
Integer[] resArrI = list.toArray(arrI);
System.out.println(Arrays.deepToString(resArrI));
}
}
 
D

Daniel Pitts

Vikram said:
Hi,
Looking at the signature of the following method in
java.util.List

public interface List<E> extends Collection<E> {
.........
........
......

<T> T[] toArray(T[] a);
}

I wrote a small program as below:

ArrayList<String> c = new ArrayList<String>();
c.add("Vikram");
c.add("Pyati");
Integer[] i = new Integer[20];
c.toArray(i);

This did not give me a compilation error, though it fails at runtime
giving java.lang.ArrayStoreException, which is perfect.

My question is , why did the above mentioned method be declared as
<E> E[] toArray(E[] a);
which will force the method to take only the array of formal type ( in
this case a String[] ) at the compile time
So, first off, Generics and Arrays don't always mix well.

Second, I think you're attempting to express this:
<T super E> toArray(T[] a);

Although, that breaks this:
List<Number> c = new ArrayList<Number>();
c.add(new Integer(3));
c.add(new Integer(15));

Integer[] i = c.toArray(new Integer[0]);

the toArray(Object[]) method is inherently a run-time only method,
because it can be used to create any type of array.
 
D

d

      Object[] arrO = new Object[list.size()];
      Object[] resArrO = list.toArray(arrO);

Alternative idiom, purely a matter of style as the net result is the same:

  Object[] resArrO = list.toArray( new Object[0] );

I point this out not to recommend it, although personally I like it, but to
alert those who may run across it from time to time.

I much prefer the 2nd example simply because you do not need the arr0
reference (which to me is syntactic clutter).
 
V

Vikram

d said:
      Object[] arrO = new Object[list.size()];
      Object[] resArrO = list.toArray(arrO);
Alternative idiom, purely a matter of style as the net result is the same:
  Object[] resArrO = list.toArray( new Object[0] );
I point this out not to recommend it, although personally I like it, but to
alert those who may run across it from time to time.
I much prefer the 2nd example simply because you do not need the arr0
reference (which to me is syntactic clutter).

You don't need it in the first idiom, really:

   Object[] resArrO = list.toArray( new Object[list.size()] );

Difference eliminated.

Thanks very much to everyone... Now I am clear
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top