participate


Generics - generic array creation [Locked]
This topic is locked
<<   Back to Forum  |   Give us Feedback
This topic has 19 replies on 2 pages.    1 | 2 | Next »
IPL
Posts:3
Registered: 12/19/01
generic array creation   
Jun 15, 2004 12:18 PM

 
Hi,

I have a problem with generic array creation.

When I try to compile the following example (see below). I always have the following error:
javac Stack.java
Stack.java:2: generic array creation
T[] pile = new T[255];
^
1 error

The code:
public class Stack<T> {
T[] pile = new T[255];
int idx = 0;

public void push(T t) {
pile[idx] = t;
idx++;
}

public T pop() {
if (idx <= 0) {
throw new RuntimeException();
}
idx--;
return pile[idx+1];
}

public static void main(String[] args) {
Stack<Element> s = new Stack<Element>();
s.push(new Element("Hello"));
System.out.println(s.pop());
}
}

What am I doing wrong ?
 
afreije
Posts:146
Registered: 11/10/98
Re: generic array creation   
Jun 15, 2004 12:45 PM (reply 1 of 19)  (In reply to original post )

 
I have a problem with generic array creation.
...
What am I doing wrong ?

There is no generic array creation in Tiger (yet I keep hoping).
What you can do (but you will get an unpleasant warning):
    T[] pile = (T[]) new Object[255];

 
Michael_Lorton
Posts:165
Registered: 6/16/03
Re: generic array creation   
Jun 15, 2004 4:50 PM (reply 2 of 19)  (In reply to #1 )

 
The obvious question is, why is there is no generic array creation in Tiger? It seems easy enough.
 
afreije
Posts:146
Registered: 11/10/98
Re: generic array creation   
Jun 15, 2004 4:55 PM (reply 3 of 19)  (In reply to #2 )

 
It would be easy if T.type were availabe at runtime, but it is not.
 
remi_forax
Posts:64
Registered: 7/3/03
Re: generic array creation   
Jun 16, 2004 1:05 AM (reply 4 of 19)  (In reply to #3 )

 
Yes, to be backward compatible, the generics doesn't carry
T at runtime.

But, the class Class exist !!
You can write your class Stack like this :
import java.lang.reflect.Array;
 
class Stack<T> {
  public Stack(Class<T> clazz,int capacity) {
     array=(T[])Array.newInstance(clazz,capacity);
  }
 
  private final T[] array;
}
 
IPL
Posts:3
Registered: 12/19/01
Re: generic array creation   
Jun 16, 2004 1:32 AM (reply 5 of 19)  (In reply to #4 )

 
Thanks for all your answers :)
 
GarretWilson
Posts:195
Registered: 10/24/99
Re: generic array creation   
Oct 26, 2004 8:48 AM (reply 6 of 19)  (In reply to #5 )

 
Here are some follow up questions from a similar query I posted on the general JSDK forum.

It's perfectly valid to have a method with a generic array as a parameter, such as verify(MyClass<String>[] myClasses). Now, if I can receive an array of generics in a method, I must have been able to create them at some point---that reasoning seems perfectly logical to me. Java 5.0 generics apparently doesn't allow creating the array in a type-safe manner, though. Instead, I have to pass new MyClass[10] to the method, which means I lose the type-safety generics was supposed to bring.

In fact, the tutorial by Gilad Bracha (Section 7.3 page 15) says that, "We've had type-safety as a primary design goal of generics. In particular, the language is designed to guarantee that if your entire application has been compiled without unchecked warnings using javac -source 1.5, it is type safe." (emphasis in original) Unfortunately, there's no way to use arrays of generics without unchecked warnings. Even if I cast my array of raw types to an array of generics when I pass it to a method that expects an array of generics, the cast is flagged as an unchecked cast.

I can, however, create a method with varargs (which we all know are implemented as arrays) such as verify(MyClass<String>... myClasses), and then inside the method assign the varargs to an array of MyClass<String>. In fact, I could even create the following utility method:

public static <T> T[] createArray(T... items)
{
  return items;
}


Won't this create an array of generics for me, with no unchecked warnings? (The problem is that with varargs I have to know at compile time how many items will be in the array when I call the method.)

This all doesn't make sense to me. If a method can have arrays with generics passed as arguments, why can't they be created?

Thanks,

Garret
 
jschell
Posts:38,148
Registered: 11/3/97
Re: generic array creation   
Oct 26, 2004 9:11 AM (reply 7 of 19)  (In reply to #6 )

 
See this thread and reply 12

http://forum.java.sun.com/thread.jsp?forum=316&thread=564355
 
Screen1314
Posts:1
Registered: 1/9/05
Re: generic array creation   
Jan 9, 2005 8:39 AM (reply 8 of 19)  (In reply to original post )

 
Generic types are compile time types. That's why it's not possible to create an array of generic type, the length of the array is known only at run time.

I propose another solution: replace the array with a collection. You'll have a collection of collection already at compile time and no discussion: It looks like this for a matrix 2x2:

ArrayList<ArrayList<Object>> aaL = new ArrayList<ArrayList<Object>>();
aaL.add(new ArrayList<Object>());
aaL.add(new ArrayList<Object>());
aaL.get(0).add("00");
aaL.get(0).add("01");
aaL.get(1).add("10");
aaL.get(1).add("11");
System.out.print(aaL.get(0).get(0).toString()"\n");
System.out.print(aaL.get(0).get(1).toString()
"\n");
System.out.print(aaL.get(1).get(0).toString()"\n");
System.out.print(aaL.get(1).get(1).toString()
"\n");

There's probably no performance penalty !

Denis
 
radhamohan
Posts:31
Registered: 1/13/99
Re: generic array creation   
Jan 10, 2005 2:25 AM (reply 9 of 19)  (In reply to #4 )

 
Or else like this. I see source like this

public <T> T[] toArray(T[] a) {
a = (T[])java.lang.reflect.Array.
newInstance(a.getClass().getComponentType(), size);
return a;
}

Mohan
 
tazzu
Posts:3
Registered: 8/30/02
Re: generic array creation   
Jan 13, 2005 2:05 AM (reply 10 of 19)  (In reply to #1 )

 
I have a problem with generic array creation.
...
What am I doing wrong ?

There is no generic array creation in Tiger (yet I
keep hoping).
What you can do (but you will get an unpleasant
warning):
    T[] pile = (T[]) new Object[255];



I think this will give you not only an "unpleasant" warning,
but also a runtime exception
"ClassCastException" java.lang.ClassCastException: [Ljava.lang.Object;


In general you get a runtime exception doing this in java:

Object[] obs_ok = new String[2];
Object[] obs_ko = new Object[2];

String[] strs;

strs = (String[])obs_ok; // THIS IS OK
strs = (String[])obs_ko; // THIS IS NOT OK

( furthermore, this is a tipical question in java certification exam SCJP !!! : ) )
 
dhall
Posts:269
Registered: 5/16/97
Re: generic array creation   
Jan 13, 2005 6:07 AM (reply 11 of 19)  (In reply to #8 )

 
Generic types are compile time types. That's why it's not possible to create an array of generic type, the length of the array is known only at run time.

Just a minor clarification: it is not the length of the array that is only known at run time, it is the specific type of objects that the array can contain. The amount of memory necessary to contain the array object itself is known when the array is created, and is not a function of the type of objects stored in the array, because the array object doesn't store the actual objects themselves: only constant size references to objects that may or may not exist somewhere in the heap.

Dave Hall
http://jga.sf.net/
http://jroller.com/page/dhall/
 
t0farr
Posts:7
Registered: 3/25/06
Re: generic array creation   
Mar 25, 2006 2:32 PM (reply 12 of 19)  (In reply to #10 )

 
I would have thought this would fail to, so I tried it and it actually does work!
Go ahead and try the code below

public class TestGenericArray<T>
{

public static void main(String[] args)
{
TestGenericArray<String> ti = new TestGenericArray<String>();
ti.test("String1","String2");
}


public void test(T... elements)
{
T [] t = (T [])(new Object[elements.length]);
for(int i = 0; i < t.length; i++)
System.out.println((t[i] = elements[i]));
}
}
 
kablair
Posts:2,045
Registered: 4/26/03
Re: generic array creation   
Mar 27, 2006 4:13 PM (reply 13 of 19)  (In reply to #8 )

 
Generic types are compile time types. That's why it's
not possible to create an array of generic type, the
length of the array is known only at run time.

In a word: no. The fundamental problem is the covariance of arrays.
 
raj41679
Posts:8
Registered: 8/28/03
Re: generic array creation   
Apr 4, 2006 10:37 AM (reply 14 of 19)  (In reply to #12 )

 
T0farr - I modified your class - I get a class cast exception at runtime - so I don't think you can simply cast the Object array back to the generic array:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object;
at collection.TestGenericArray.main(TestGenericArray.java:15)

public class TestGenericArray<T> {

public static void main(String[] args) {

TestGenericArray<String> ti = new TestGenericArray<String>();

String[] a = ti.test("String1", "String2");

for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}

public T[] test(T... elements) {

T[] t = (T[]) (new Object[elements.length]);

return t;
}
}
 
This topic has 19 replies on 2 pages.    1 | 2 | Next »
Back to Forum
 
Read the Developer Forums Code of Conduct

Click to email this message Email this Topic

Edit this Topic
  
 
 
Forums Statistics
    Users Online : 28
  • Guests : 133

About Sun forums
  • Oracle Forums is a large collection of user generated discussions. It is here to help you ask questions, find answers, and participate in discussions.

    Check out our guide on Getting started with Oracle Forums for a full walkthrough of how to best leverage the benefits of this community.

Powered by Jive Forums