-
-
Notifications
You must be signed in to change notification settings - Fork 340
Description
I encountered a little problem while looking at the Sponge Implementation and extending existing events.
The issue
I can overwrite every method to return a more precise result than the base interface specifies. However using the Optional destroys that benefit if used the way we currerntly do.
Here is an example code
public interface Test {
Optional<Test> getSelf();
Optional<? extends Test> getBetterSelf();
}and the second file
public class Proof implements Test {
@Override
// public Optional<Proof> getSelf() { - NOT POSSIBLE
public Optional<Test> getSelf() {
// return Optional.of(this); - NOT POSSIBLE
return Optional.of((Test) this);
}
@Override
public Optional<? extends Proof> getBetterSelf() {
return Optional.of(this);
}
public void foo() {
Proof self = getBetterSelf().get();
// Proof self2 = test.getSelf().get(); - NOT POSSIBLE
Proof self2 = (Proof) test.getSelf().get();
}
}Image the Sponge server itself has a specific subclass for one of its events, which uses a subclass of the original class/interface because a method was added that is required for further use. So if you listen to the given event and you try to get it, you will actually get the base interface because you have to downcast it, but if you use the <? extends T> for example this is no longer an issue you class can simply overwrite the return type and everything will be fine.
If we change it we have basically three benefits:
- Avoid unnecessary casting while creating the
Optional - Avoid unnecessary casting while getting the
Optional's value - Allow other APIs to extend our API more safely and freely.
I suggest replacing/changing it in the entire API (where the Optional references a class within the org.spongepowered.api.** package) , i also offer my help to change it.
This would also include immutable Iterables, Collections, ...., Maps.