I am wondering if it is possible to restrain a method declared on an interface to require a type within a type bound. In effect, I'd like to offer a method for casting a type that is somewhat type-safe in the absense of being able to provide real type-safety.
As an example, consider a hierarchy with a base type Base
which is inherited via an intermediate interface. Typically, one knows about a type being of interface FirstInterface
but not what specific class is implementing it. I'd like a method that allows casting to either implementation of an interface without allowing to cast to other implementations of Base
as demonstrated in the following example:
interface Base<TYPE extends Base<TYPE>> {
default <CAST extends TYPE> CAST as(Class<? extends CAST> type) {
if (type.isInstance(this)) {
return type.cast(this);
} else {
throw new IllegalArgumentException();
}
}
}
interface FirstIface<TYPE extends FirstIface<TYPE>> extends Base<TYPE> { }
class FirstClassA implements FirstIface<FirstClassA> { }
class FirstClassB implements FirstIface<FirstClassB> { }
interface SecondIface<TYPE extends SecondIface<TYPE>> extends Base<TYPE> { }
class SecondClassA implements SecondIface<SecondClassA> { }
class SecondClassB implements SecondIface<SecondClassB> { }
interface ThirdIface<TYPE extends ThirdIface<TYPE>> extends FirstIface<TYPE>, SecondIface<TYPE> { }
class ThirdClassA implements ThirdIface<ThirdClassA> { }
class ThirdClassB implements ThirdIface<ThirdClassB> { }
I'd hope to being able to make the following code compile in Java:
FirstIface<?> i = new FirstClassA();
FirstClassA a = i.as(FirstClassA.class); // desired: compiles, now: compiler error
FirstClassB b = i.as(FirstClassB.class); // desired: runtime exception, now: compiler error
The same should work for the hierarchy of ThirdIFace
, whereas the following code should render a compiler error:
SecondIface<?> i = new SecondClassA();
SecondClassA a = i.as(SecondClassA.class); // now and desired: compiler error
SecondClassB b = i.as(SecondClassB.class); // now and desired: compiler error
Is there any way to declare Base.as
to withhold this requirement? The code is auto-generated, so it would also be possible to provide an override in the interfaces which are auto-generated (as are the classes). When overrides are used, a scenario of SecondIface extends FirstIface
.