Consider the following two classes:
public interface Foo<T>
{
public T moo();
}
public class IntFoo implements Foo<Integer>
{
public int moo()
{
return 0;
}
}
This code will produce an error at public
int
moo
, saying that int
is incompatible with the overridden method's return type Integer
. Strictly speaking, this is true, since int
does not directly equal Integer
. However, we all know that they can be implicitly converted to each other using auto(un)boxing. What is less know is the fact that the compiler generates a bridge method in this example:
public class IntFoo implements Foo<Integer>
{
public <synthetic> <bridge> Object moo()
{
return this.moo(); // upcast
}
public Integer moo() {
return 0;
}
}
This has to be done because the JVM differentiates between return types when resolving methods, and since the erased return type of Foo.moo
is Object
, the compiler generated a bridge method with the same signature as the method.
I am wondering why this wouldn't work with primitive polymorphic return types as well:
public class IntFoo implements Foo<Integer>
{
public <synthetic> <bridge> Object moo()
{
return Integer.valueOf(this.moo());
}
public int moo()
{
return 0;
}
}
There doesn't seem to be any reason not to have this feature:
IntFoo intFoo = new IntFoo();
Foo<Integer> foo = intFoo;
Integer i = foo.moo(); // calls the synthetic method, which boxes the result of the actual implementation
In fact, this screenshot of a REPL session shows that I was even able to implement this in my custom programming language (which compiles down to Java bytecode):