javaclasscompiler-errors

Recursive invocation due to dynamic class cast


I have an interface Commodity, that is a supertype of Item and Consumable enums.
Also, there is a class Option with constructors accepting each of them with an int:

class Option{
    Option(Item c,int price){. . .}
    Option(Consumable c,int price){. . .}
    Option(Commodity c,int price){
        this(c.getClass()!=Commodity.class?c.getClass().cast(c):Item.EMPTY,price);
    }
}
}

The third constructor should determine the type of a Commodity passed and call one of other constructors with the right type.

Compiler tells me, that this will lead to an infinite recursion, and I can not understand, why.

Recursive constructor invocation Option(Commodity, int)

What is wrong with my code?


Solution

  • Unsurprisingly, the compiler isn't actually wrong here. Let's look at the separate parts of your code:

    I'm going to assume that both Item and Consumable extend Commodity.

    Item.EMPTY: We can assume this is of type Item.

    c.getClass().cast(c): This does nothing. It's always going to be of type Commodity.

    c.getClass()!=Commodity.class?c.getClass().cast(c):Item.EMPTY will then resolve to the common supertype. That's Commodity.

    The compiler has no choice but to choose the Commodity overload, and that's what makes it a recursive call.

    All in all, what you are trying to do is call a different constructor overload based on a conditional. That's simply not possible in Java. Instead, you should make a factory method:

    static Option create(Commodity commodity, int price) {
      return commodity instanceof Consumable ? new Option((Consumable) commodity, price) : new Option(Item.EMPTY, price);
    }