2

I have the following method that can return different types of Storable (ex: Food, Ore).

Inventory.java

public Storable get(Class<? extends Storable> cls) {
    for (Storable storable : inventory) {
        if(cls.isInstance(storable)) {
            this.inventory.remove(storable);
            return storable;
        }
    }
    return null;
}

It works, however I'm forced to cast my result like below:

Food food = (Food) inventory.get(Food.class);

With Java 15 and above, we can define casted object directly with instanceof (link to javadoc). I'm wondering if I can use this new syntax and return casted object directly.

I tried this but instanceof keyword only works with type not variable:

public Storable get(Class<? extends Storable> cls) {
    for (Storable storable : inventory) {
        if(storable instanceof cls castedItem) {  //cls cannot be resolved to a type
            this.inventory.remove(storable);
            return castedItem;
        }
    }
    return null;
}
Zerak
  • 38
  • 6
  • 4
    Use a generic type on the method itself: `public T get(Class cls) { ... }`. No need for any Java 15 features. – Rogue Jun 07 '22 at 16:17

1 Answers1

7

Make your method generic:

public <S extends Storable> S get(Class<S> cls) {
    for (Storable storable : inventory) {
        if (cls.isInstance(storable)) {
            this.inventory.remove(storable);
            return cls.cast(storable);
        }
    }
    return null;
}

Note the use of cls.cast. That's like (S) storable but without the compiler warning.

Rob Spoor
  • 6,186
  • 1
  • 19
  • 20