Multiple classes in an (undefined) ArrayList?

Hi!
So a while ago I realised you could make ArrayLists with no class associated.

ArrayList sampleList = new ArrayList();

I am working on a simple 2d platformer at the moment and created a class that contains the gravity function and all the needed variables, which all the other gravity-affected objects could inherit from. I would like to put all those “physicsObjects” into an ArrayList (for example all the enemies and powerUps). The thing is that the instance of an Object class can not execute the functions of a player or enemy class. And if I created a playerClass object, it could not get any object from the sampleList.

void draw(){
  Object aPhysicalObject = new Object();
  playerClass aPlayer = new Player();
  for(int i = 0; i < sampleList.size(); i++){
    aPhysicalObject = sampleList.get(i); //works
    aPhysicalObject.display(); //doesn't work
    //-----------------------------------------
    aPlayer = sampleList.get(i); //doesn't work
    aPlayer.display(); //works
  }
}

If I could check which class the indexed-object had, maybe I could get it to work? I’m looking forward to your ideas! :smiley:

1 Like

This is the same as
ArrayList<Object> sampleList = new ArrayList<Object>();

Now an array list can hold objects of the <class> or any class that inherits from it. Since Object is the base class for all Java classes, including user defined classes your array list can hold objects of any type. The problem with this is that many poorly written programs crashed at runtime due to class casting exceptions.

This was the case before the Java developers introduced generics, now we type all our collections
ArrayList<MyUserClass> sampleList = new ArrayList<MyUserClass>();
The poorly written code is now detected at compile time so the running program is much more stable.

2 Likes

@quark Okay so I understood that you can add any subclass to an ArrayList, but how do I get the code from before to work? Is that even possible? :sweat_smile:

Try this

aPlayer = (playerClass) sampleList.get(i);

What was the error message?

1 Like

So I don’t have much time right now but I put that line in and it didn’t give me an error message. I’ll have to adjust my code later to see if it really works! One question though: What exactly does that do? Is it like “if sampleList(i) == playerClass get it else do nothing” or what?

In your code

  • aPlayer if of type playerClass
  • sampleList holds instances of type Object
  • sampleList.get(i); returns an instance of type `Object’

A variable of type playerClass can not reference an instance of type Object so
aPlayer = sampleList.get(i);
fails

In this code
aPlayer = (playerClass) sampleList.get(i);
the returned Object instance is cast to the type playerClass so it’s reference can be stored in a playerClass variable i.e. aPlayer hence it works. The technique is called casting

The problem with this code is, if the returned instance is not of type playerClass (or a child class of playerClass) then the statement
aPlayer = (playerClass) sampleList.get(i);
will crash at runtime.

That is why you never see lists declared like this
ArrayList sampleList = new ArrayList();
except in ancient legacy code.

4 Likes

Okay, thank you! :smiley:

Depending on what you want to do with the objects in the list, you can either inherit all your gravity objects from a common gravityObject class and cast to this when accessing members of the list. Or you create a common gravity object interface which exposes the gravity methods for all objects in the list. You can cast to an interface type just like you cast to any parent object type.

What’s an interface? :sweat_smile:

It’s like a contract a class must fulfill. If a class implements an interface, it must provide all the fields and methods defined in the interface. Make a quick search about “java interface” and you will find a lot resources. Happy coding :slight_smile:

Not the fields. Actually, any fields declared in an interface are implicitly public, static & final! :no_mouth:

1 Like

6 posts were split to a new topic: Redundant declarations in interface PConstants

@quark :

Can I ask the object which type it is?


    println(someObject.getType());

You can get any object to report the class it was instantiated from

// Object hierarchy
class A{ }
class B extends A { }
class C extends B { }

// Declare 3 variables of type A
A a,b,c;

// Now instantiate an object from each class
a = new A();
b = new B();
c = new C();

// Get each object to report its class name
println(a.getClass().getSimpleName());
println(b.getClass().getSimpleName());
println(c.getClass().getSimpleName());
1 Like

this seems to work:


// imports ----

import java.lang.reflect.Field;
import java.util.Collections;

....
...
....


  println("---------------------------------------------------------");

  println("\n*****  METHODS  *****");
  for (java.lang.reflect.Method c : getClass().getDeclaredMethods()) {
    //
    println("-----------------------------");

    println(c.getClass());

    println((String) c.getName());
  }//for

cf. Object (Java Platform SE 7 )
cf. Class (Java Platform SE 8 )
cf. Method (Java Platform SE 8 )

1 Like
    println(c.getClass());

Can I ask the Method c which methods it is using (which OTHER methods it is calling) ?

Interesting question but AFAIK there is no simple way to do this.

The source code in the c would be compiled to Java byte code before execution and I don’t think the compilation process preserves the variable and method names from the source code by default.

2 Likes

Just a thought :thinking:

If a sketch crashes with an un-handled exception it produces a stack trace which lists the methods called preceding the exception so the JVM knows what methods have been executed but that still doesn’t mean it knows what method calls are coming up.

1 Like

I see that an Object has Member: Method (Java Platform SE 8 )

How can I get the members or a member Object from my method?

1 Like

@quark

Question One

Cool would be when a method could tell us it’s name

  println("I am "
    + this.getClass().getName());

but that’s only the name of the Sketch!

How can I get the name of the method I am in?


Question Two

And can i retrieve the full text of a method:

  for (java.lang.reflect.Method currentMethod : getClass().getDeclaredMethods()) {

    print("toString() gives : ");
    println(currentMethod.toString()); // works, gives only header


    println(currentMethod.getBody()); // ????????????????????
}
2 Likes