Results 1 to 11 of 11
Thread: confused about Generics
- 10-18-2010, 07:00 PM #1
Member
- Join Date
- Jun 2010
- Posts
- 86
- Rep Power
- 0
confused about Generics
Hello,
I'm somewhat of a newbie to Generics (A.K.A. templates I believe) and I'm playing around with something pretty sophisticated. I'm encountering some warnings when compiling (unchecked calls) and I'm not sure how to deal with them. I'm also trying to deliberately create an error without much success.
Here's a SSCCE:
So I have a couple questions:Java Code:import java.util.Vector; // Possession class class Possession<T> { private Vector<T> itemVector; public Possession() { itemVector = new Vector<T>(10, 5); } public void add(T item) {itemVector.add(item);} public Vector<T> getVector() {return itemVector;} } // Item class class Item { protected String name; public Item() {} public void print() { System.out.println("I am a " + name); } } // Lock class class Lock extends Item { public Lock() {name = "Lock";} } // Key class class Key extends Item { public Key() {name = "Key";} } // Main class public class Main { private Possession[] possessions; public Main() { possessions = new Possession[2]; possessions[0] = new Possession<Lock>(); possessions[1] = new Possession<Key>(); } public void addPossession(int index, Item i) { possessions[index].add(i); } public void print() { ((Item)possessions[0].getVector().get(0)).print(); ((Item)possessions[1].getVector().get(0)).print(); } public static void main(String args[]) { Main m = new Main(); // constructor creates possessions[2] = {new Possession<Lock>(), ...<Key>()} m.addPossession(0, new Key()); // add a Key to possessions[0] when it should be a Lock m.addPossession(1, new Lock()); // add a Lock to possessions[1] when it should be a Key m.print(); // print possessions to show they were indeed added without error } }
1) When compiling with -Xlint:unchecked, it tells me that the line possessions[index].add(i) in the method Main.addPossession(int,Item) is unchecked. I've looked up how to resolve this problem and everything I've found says to specify the generic type. But I don't see a way to do so in this case. For example, I've found this on the net:
But since I'm dealing with an entry in an array, and since each entry is of a different generic type, and since the value for the argument 'index' will vary, there's no way I can specify the exact generic type (short of it being an instance of Item).Java Code:ArrayList <Double> L = new ArrayList<Double>(); L.add(new Double(56.3));
Is there some other way around this?
2) Shouldn't my code result in a run time error? I'm adding a Key to possessions[0] whose generic type is Lock and I'm adding Lock to possessions[1] whose generic type of Key. Yet no error occurs (either at compile time or run time), and this is verified by the call to print().
- 10-19-2010, 09:09 AM #2
Moderator
- Join Date
- Apr 2009
- Posts
- 10,481
- Rep Power
- 16
1) Your possessions array is not an array of any old class T, though, is it?
It's and array of Items, so it should be declared as such.
2) No, your possessions array is of any class, since you did not declare it as Possession<Item> (for example)...consequently each entry in the array can be of any class.
- 10-19-2010, 09:56 AM #3
- Join Date
- Sep 2008
- Location
- Voorschoten, the Netherlands
- Posts
- 11,410
- Blog Entries
- 7
- Rep Power
- 17
Arrays are covariant and generics and arrays don't go well together; e.g. the following compiles fine:
... but it generates an ArrayStoreException when run; not so with collections, i.e. a List<Number> isn't a List<Integer> although an Integer is a Number. Also read this article.Java Code:Integer[] ia= new Integer[1]; Number[] na= ia; na[0]= new Double(1.23); System.out.println(ia[0]);
kind regards,
Jos
- 10-19-2010, 10:03 AM #4
Moderator
- Join Date
- Apr 2009
- Posts
- 10,481
- Rep Power
- 16
So what are you saying?
That Possession<Item>[] is not correct?
That you can't declare an array of generic things?
ETA:
That compiles, but I can't say if it'll run once you try and actually do things with the arrayArray.Java Code:public class Scratch { public static void main (String[] args) { ArrayList<Scratch> scrarray = new ArrayList<Scratch>(); ArrayList<Scratch>[] arrayArray = new ArrayList[10]; arrayArray[0] = scrarray; } }
You do get an unchecked assignment on the arrayArray initialisation, though...Last edited by Tolls; 10-19-2010 at 10:07 AM.
- 10-19-2010, 10:14 AM #5
- Join Date
- Sep 2008
- Location
- Voorschoten, the Netherlands
- Posts
- 11,410
- Blog Entries
- 7
- Rep Power
- 17
Yup, that's what I'm saying the covariance of arrays (an incorrect decision in hindsight) doesn't agree with the strict type checking of generics; the latter is full of compromises ... (that IBM article is a good one and has some nice links too that explain this mess quite well).
kind regards,
Jos
- 10-19-2010, 10:38 AM #6
Moderator
- Join Date
- Apr 2009
- Posts
- 10,481
- Rep Power
- 16
Got it.
Because Possession<Lock> cannot be assigned to something that is a Possession<Item> (because a Possesion<Lock> is not a Possession<Item>), attempting to assign a Possession<subclass of Item> to an array of Possesion<Item>s will result in it falling over in a heap?
- 10-19-2010, 10:42 AM #7
- Join Date
- Sep 2008
- Location
- Voorschoten, the Netherlands
- Posts
- 11,410
- Blog Entries
- 7
- Rep Power
- 17
- 10-19-2010, 05:38 PM #8
Member
- Join Date
- Jun 2010
- Posts
- 86
- Rep Power
- 0
Thanks both for your feedback. And thanks to JosAH for the article. The first section (Generics are not covariant) explained a lot, but the rest was a little over my head (as I said, I'm a newbie to generics); I did catch the gist of it though (I think) and it seemed less relevant to what I'm trying to do.
At this point, I'm wondering if I should use an ArrayList<Possession> instead of the Possession[] array. Will I still encounter the problem with covariance? According to the article, the ArrayList class looks like this:
which means it still consists of an actual array, which in turn means I'll still probably encounter the covariance issue.Java Code:class ArrayList<V> { private V[] backingArray; //... }
I'm also wondering if this (or some variant thereof) is permissable:
ArrayList<Possession<Item>> possessionList = new ArrayList<Possession<Item>>();
(I haven't tried it but I will).
I'm also wondering if wildcards might help me, but at the moment I don't see how.
Anyway, what I'm trying to do with all this is place restrictions on my code so that if I inadvertently attempt to put a Possessions object of some generic type V (say a Lock) at an index reserved for some other type Q (say a Key), it will give me an error. This is just so that I will be able to identify inadvertent errors in my code when they happen.
I have a set of static final ints that I plan to use an indecies. For example:
static final int KEY = 0;
static final int LOCK = 1;
//...
and I just want to make sure I don't inadvertently do something like:
I was hoping that some kind of exception would occur (like a ClassCastException). But if necessary, I'll have to create some kind of method like the following (though this is what I'm trying to avoid):Java Code:Key k = new Key(); possessions[LOCK].add(k);
It's no big deal if I have to do this, but it would be nice (and more clean/elegant) if I didn't.Java Code:boolean validateIndex(int index, Item i) { try { switch (index) { case KEY: (Key) i; break; case LOCK: (Lock) i; break; //... } } catch (ClassCastException e) { return false; } return true; }
I'm sorry if the right course of action here seems obvious to other more experienced coders, but like I said, I'm just new to this and brainstorming here. Any feedback would be much appreciated.
Thanks.
- 10-20-2010, 09:01 AM #9
Moderator
- Join Date
- Apr 2009
- Posts
- 10,481
- Rep Power
- 16
You don't want to force certain types into particular indices in that array.
That's not good.
Something is wrong in your model if you find yourself having to do that.
What are you attempting to model here?
- 10-20-2010, 04:17 PM #10
Member
- Join Date
- Jun 2010
- Posts
- 86
- Rep Power
- 0
It's just a way for me to keep different subclasses of Item organized.
Originally Posted by Tolls
This is part of a video game I'm programming. The possessions array is a member of the GoodGuy class (the main character in the game). As he goes through the level, he collects Items such as weapons, health items, coins, keys, locks, etc. They get stored in the possessions array. In order to stay organized, I want to store a particular Item (like a Key) consistently at a particular index, and I'll be referencing that index with a static final int (for example, KEYS). To be precise, what I'll be storing there is not an Item object per se, but a Possession object. The Possession object contains a Vector that stores the Item object. That way, I don't have to deal with 2D array (that, for me, gets messy) - it's just a 1D array of Possessions - and yet there can be more than one Item of the same kind at a particular index (vis-a-vis the Possession's Vector).
Again, your feedback is most value. Thank you.Last edited by gib65; 10-20-2010 at 04:20 PM.
- 10-20-2010, 04:34 PM #11
Moderator
- Join Date
- Apr 2009
- Posts
- 10,481
- Rep Power
- 16
I don't see why you should want to store each item at a particular index. I'm not sure what you gain by doing that?
In any case, assuming that's somehow useful, it sounds more like a map to me, with the key being the type of possession. I'd be tempted to turn the types into an enum and use the enum as a key. So you'd have a PossessionType enum, consisting of KEY, LOCK etc etc. Each Possession subclass would be of one of these types, so would have a reference to one of these enums.
The Map would then be a Map<PossessionType, List<Possession>>, allowing you to store and retrieve your types. You can pre-populate the map with empty lists for each type at the start (otherwise you have to check if there's an entry or not).
Similar Threads
-
Help with generics
By shai in forum New To JavaReplies: 0Last Post: 08-12-2010, 07:07 AM -
Generics
By sakshamkum in forum Advanced JavaReplies: 3Last Post: 06-03-2010, 10:12 PM -
Generics
By bschmitt78 in forum Advanced JavaReplies: 3Last Post: 03-16-2010, 02:21 AM -
Generics
By sireesha in forum New To JavaReplies: 2Last Post: 01-10-2008, 11:08 PM -
Java confused over Generics?
By Bibendum in forum New To JavaReplies: 3Last Post: 12-26-2007, 06:23 AM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks