0

In Processing, I have an ArrayList of objects built from a custom class. When I use the .get() function to return one of the objects, it seems to return the object all right -- but I can't access any of the object's variables or methods. I get the error message "[variable] cannot be resolved or is not a field." Is this a bug, or am I doing something wrong?

Here's a sample. Notice the values returned from the setup() function.

// regular array
Thing[] thinglist1 = new Thing[1];

// ArrayList array
ArrayList thinglist2 = new ArrayList<Thing>(1);

// instantiate the class
Thing thing = new Thing(12345);

// class definition
class Thing {
  int var;

  Thing(int i){
    var = i;
    thinglist1[0] = this;
    thinglist2.add(this);
  };
};

// run it!
void setup(){
  println(thinglist1[0] == thinglist2.get(0));
  // true

  println(thinglist1[0].var);
  // 12345

  println(thinglist2.get(0).var);
  // ERROR: "var cannot be resolved or is not a field"
};
jrc03c
  • 301
  • 1
  • 2
  • 6
  • related: [What is a raw type and why shouldn't we use it?](http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it) – Paul Bellora Jun 23 '13 at 04:37

2 Answers2

9

You've kinda messed up your generics.

Change

ArrayList thinglist2 = new ArrayList<Thing>(1);

to:

ArrayList<Thing> thinglist2 = new ArrayList<Thing>(1);

Because you didn't specify a type, what you really had was:

ArrayList<? extends Object> thinglist2 = new ArrayList<Thing>(1);

So when you retrieved an item from it using get, it was typed as Object rather than your Thing

Edit to add: The reason for this is legacy; when generics were introduced things were put in place for backward compatibility. Unfortunately that creates situations like this which is confusing to someone new to Java.

You'd prob expect a compiler warning or error, but Java silently changes that non-generic-typed ArrayList into "Arraylist that contains something that extends Object" ... which is anything (except a primitive), because all objects implicitly extend Object

Brian Roach
  • 76,169
  • 12
  • 136
  • 161
  • I would just say "what you really had was: `ArrayList` ..." - since it's more accurate and adding wildcards to the mix could be confusing. – Paul Bellora Jun 23 '13 at 04:22
  • @PaulBellora - already fixed that in an edit - refresh ;) I think stating what's really happening is more accurate, and then explaining why. – Brian Roach Jun 23 '13 at 04:23
  • Right, I'm saying I would change it back. – Paul Bellora Jun 23 '13 at 04:24
  • I understand your point, I just disagree that posting something incorrect is "more accurate". "Easier to understand" perhaps, but certainly not accurate. – Brian Roach Jun 23 '13 at 04:31
-2

In the last line you must cast return value from get function to the array of object.

System.out.println(((Thing[])thinglist2.get(0))[0].var);
Vahid
  • 137
  • 8