If I have this interface:
public interface Foo {
void bar();
}
Why can't I implement it like this?
public class FooImpl implements Foo {
@Override
public Object bar() {
return new Object();
}
}
It seems like void should be covariant with everything. Am I missing something?
Edit: I should have been clearer that I'm looking for the design justification, not the technical reason that it won't compile. Are there negative consequences to making void covariant to everything?
void
is only covariant with void
because the JLS says so:
A method declaration d1 with return type R1 is return-type-substitutable for another method d2 with return type R2, if and only if the following conditions hold:
If R1 is
void
then R2 isvoid
.If R1 is a primitive type, then R2 is identical to R1.
If R1 is a reference type then:
R1 is either a subtype of R2 or R1 can be converted to a subtype of R2 by unchecked conversion (§5.1.9), or
R1 = |R2|
covariance means that if your methods return type
is a Supertype object
you can return sub-type Object
at runtime, void is not the super type of java.lang.Object
(or any Object for that matter except itself as answered by MR NPE)
Technically void
cannot be a covariant return type as the caller needs to know the stack layout.
Calling a function that returns an object would result of an object-ref on the top of the stack after the INVOKEVIRTUAL/INTERFACE. Void
return type leaves nothing on the top of the stack, hence the functions are binary incompatible.
So the JLS rightfully says it's not possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With