0

I've added a generic method to an interface, so that every class which implements that interface has a fluent method to set a parameter on that class, but I'm getting "Unchecked cast" warning on the return statement, so I'm suppressing it.

Since I'm uncomfortable with just suppressing the warning, and casts have always felt like code smells since I came to java from C#, where they most definitely are, I wonder under what circumstances that warning might apply. Alternatively, I wonder if there is a more type safe way of implementing what I want.

Wanting to be able to use

var model = new MyModel().withBoundsToFit(true);

rather than

var model = new MyModel();
model.setBoundsToFit(true);

I created this method in IBoundsToFit:

//@SuppressWarnings("unchecked")
default <T extends IBoundsToFit> T withBoundsToFit(boolean boundsToFit) {
    setBoundsToFit(boundsToFit);
    return (T) this; // Type safety: Unchecked cast from IboundsToFit to T
}

What I don't understand is how, when I'm already constraining T to classes which extend IBoundsToFit, in what situation it could be unsafe to do this cast.

Mark Booth
  • 7,605
  • 2
  • 68
  • 92
  • [This answer](https://stackoverflow.com/a/44323160/5133585) should explain exactly in what sense is it "unchecked". For more examples, see [this](https://stackoverflow.com/q/2693180/5133585). – Sweeper Oct 13 '22 at 14:15

1 Answers1

1

The problem is that setting the generic return type means that the caller gets to decide the return type not the implementing class. For instance the below example compiles but fails at runtime with a ClassCastException.

public class Demo {
    public static void main(String[] args) {
        A foo = new B().withBounds(false);
    }
}

interface Bounds {
    void setBounds(boolean bounds);
    default <T extends Bounds> T withBounds(boolean bounds) {
        this.setBounds(bounds);
        return (T) this;
    }
}

class A implements Bounds {
    public void setBounds(boolean bounds) {}
}

class B implements Bounds {
    public void setBounds(boolean bounds) {}
}
Holloway
  • 6,412
  • 1
  • 26
  • 33
  • So as long as we document the `withBounds` method suggesting people use `var foo = B().withBounds(false)` in practice this is unlikely to ever happen? – Mark Booth Oct 13 '22 at 17:01