0

I've written a class which accepts a generic type, and I'm trying to create an array list of generic arrays within it. I understand that Java can't create generic arrays, but I also know there are workarounds. Is there a way the below code can work, or am I barking up the wrong tree?

public class IterableContainer<T extends IterableItem> {
    private T[] itemArray;

    // how can i get this following line to work?
    private List<T[]> items = new ArrayList<T[10]>();

    public IterableContainer() {  

... etc ...

Ignore past here - turns out it was an IDE issue.
Left in for continuity of questions and answers.

EDIT:

This also doesn't work:

private List<T[]> items = new ArrayList<T[]>();

with the error:

Syntax error on token ">", VariableDeclaratorId expected after this token

Community
  • 1
  • 1
Martyn
  • 16,432
  • 24
  • 71
  • 104

5 Answers5

4

It works just fine, you just can't use the T[10] declaration as the length of an array doesn't affect its type.

i.e.

... = new ArrayList<T[]>();

Not saying it's a great idea, but it should be possible with the same restrictions on generic arrays as always. Creating stuff to put in your list will give you a headache.

Mark Peters
  • 80,126
  • 17
  • 159
  • 190
  • This is what I had initially, but it's giving me an issue in Eclipse (although it's not underlining anything as being in error) - 'Syntax error on token ">", VariableDeclaratorId expected after this token'. Is this just an Eclipse issue or is there something more to it? – Martyn Jun 15 '11 at 13:32
  • It runs fine here (NetBeans). Maybe your mistake is somewhere else. – toto2 Jun 15 '11 at 14:23
  • 1
    Stop using Eclipse as some kind of authority of Java syntax. Ahhh! – irreputable Jun 15 '11 at 18:06
4

"... barking up the wrong tree..., use a List<List<T>>. Using raw arrays in Java is almost always a code smell, there is no reason not to use the proper collection classes.

  • I'm developing for mobile devices, so always try and use basic types when possible as thought it was less resource hungry. Is this something I shouldn't really be worried about? – Martyn Jun 15 '11 at 13:35
  • 3
    you are prematurely optimizing –  Jun 15 '11 at 16:40
  • 1
    @Martyn: An ArrayList is just an array with a few bytes of overhead and a much nicer interface. It will be marginally but trivially slower and will encapsulate all the headaches you would have with generic arrays. – Mark Peters Jun 15 '11 at 16:54
  • Lesson learned. Weirdly I didn't spot this as prematurely optimising - more being cautious. In hindsight it does appear to have all the hallmarks of optimisation. A few changes to how the code works, but now have 'private Map> itemsByType = new HashMap>();' which works great. Thank you. – Martyn Jun 16 '11 at 08:33
  • @Martyn anytime you are doing something for "performance" reasons without actually profiling it to see if it is actually an issue, is an indication of premature optimization. Doing something like initializing your `List` to the number of items it is expected to hold, or a little more, is correct usage and not premature optimization, because it is an intended usage of the class's behavior. –  Jun 16 '11 at 15:26
  • and you're prematurely blaming arrays, when that's not the actual problem in this case, as (as other answers have pointed out) declaring a list of generic arrays does work – newacct Jun 17 '11 at 05:55
  • raw `Arrays`, `Vector`, `Enumeration` and `Hashtable` are 1995 constructs and have no place in idiomatic Java in 2011 –  Jun 17 '11 at 06:12
1
private List<T[]> items = new ArrayList<T[]>();

works fine in my machine

When you say "I'm developing for mobile devices" ....are you targeting j2me? There is no support for generics in j2metargetng

Pablo Grisafi
  • 5,039
  • 1
  • 19
  • 29
1

This is a valid declaration in java (according to spec) and compiles just fine with javac as others have commented.

public class IterableContainer<T extends IterableItem> {
  private T[] itemArray;

  private List<T[]> items = new ArrayList<T[]>();// valid

  ..........  

}

I believe the error you are seeing is not emitted from Eclipse, possibly coming from an Android SDK configured in Eclipse. If you create a Java Project in Eclipse, this code should work just fine. If you use this in an Android Project in Eclipse, you are likely to run into this one. I had this error when running this code from an Android project :

#  guarantee(_name_index != 0 && _signature_index != 0) failed: bad constant pool index for fieldDescriptor

Sounds like you are restricted in an Android project, unfortunately.

Arul Dhesiaseelan
  • 2,009
  • 23
  • 19
-1

You have not defined T in this code.

If you are creating a generic class, you need to write:

public class <T extends IterableItem> IterableContainer...

The next problem in your code is that you are trying to initilize items of ArrayList during its construction. It is impossible. You should rather write:

private List<T[]> items = new ArrayList<T[]>();

Jacek L.
  • 1,376
  • 14
  • 19