Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I call an instance method from a generic object?

Say I have an arrayList containing items of different classes, all of them having the same method: draw(); I have a third class with a method drawItems() that takes in the arrayList as a parameter. Now, how can I call the draw() method on those objects if they are passed as generic objects?

This below doesn't work. I can see why. Java doesn't know the item has such a function. How can I get around this?

public void drawItems(ArrayList<T> data) 
{
    data.forEach((T item) -> {
        item.draw();
   }); 
}

UPDATE

Thank you everyone. I did it as follows:

1) Create interface named Drawable:

public interface Drawable {
    public void draw();
}

2) Implement interface into Item class:

public class Item implements Drawable { 

    @Override
    public void draw(GraphicsContext gc) {
        //...
    }
}

3) Adjust drawItems:

public void drawItems(ArrayList<Drawable> data) {

    data.forEach((Drawable item) -> {
        item.draw();
    });
}
like image 238
swyveu Avatar asked Jan 25 '19 00:01

swyveu


People also ask

How do I get a class instance of generic type T?

The short answer is, that there is no way to find out the runtime type of generic type parameters in Java. A solution to this is to pass the Class of the type parameter into the constructor of the generic type, e.g.

Which of the following allows us to call generic methods as a normal method?

This feature, known as type inference, allows you to invoke a generic method as an ordinary method, without specifying a type between angle brackets. This topic is further discussed in the following section, Type Inference.

How do you declare a generic method How do you invoke a generic method?

Generic MethodsAll generic method declarations have a type parameter section delimited by angle brackets (< and >) that precedes the method's return type ( < E > in the next example). Each type parameter section contains one or more type parameters separated by commas.


1 Answers

Your T type parameter is unbounded, so the compiler makes no assumptions about the methods guaranteed to be available (except for Object methods). That's why it can't find the draw method.

Do your classes that have the draw method inherit from some superclass or interface that declares the draw method? If not, create that interface, e.g. Drawable.

Then change the parameter data to be of type List<? extends Drawable>, so you can pass in a List<Drawable> or e.g. a List<DrawableSubclass>.

If instead you must use the type parameter T, declare T (I'm assuming it's on the class) to be T extends Drawable.

Either way, with the upper bound, everything in the List will be Drawable, so the compiler knows that any objects in that list will have a draw method.

like image 132
rgettman Avatar answered Sep 18 '22 00:09

rgettman