in each case, which method is invoked first, the bridge method or the typed method? Which method is the one that is actually overriding Foo#foo(T) (aka Foo#foo(Object))?
My logical guess is that the synthetic method is called first and is the actual overriding method, for its method signature matches its superclass's method signature, but I'm not sure what the JVM really does. Would bar.foo(42) and foo.foo(42) call the same method, or would bar.foo(42) call the typed method to avoid the overhead of having to "go over the bridge"?
You have instance methods in there, so the execution depends completely upon the instance present in those variables with which you are invoking the methods in runtime.
In your code, both 'bar' and 'foo' variables will have 'Bar' instance in runtime and so that class's method will be invoked.
If Bar overrides Foo's foo(), then in both cases Bar's foo() will be invoked.
The output will be:
foo in Bar
foo in Bar
Now consider below code where foo is not actually overridden:
The output will be :
foo in Bar
The driver code is:
The biggest gamble will be to ask a question whose answer you know in that it will challenge your theory | www.TechAspire.blogspot.in
The synthetic/bridge method is generated by the compiler to preserve the polymorphism of generic types after type erasure. That seems to indicate to me that the bridge only gets involved when static binding happens at compile time. Or maybe not. Normally, polymorphism involves dynamic binding so if the correct method to execute is determined at runtime, I would think that there would be no need to go through the bridge method. But then again, the dynamic binding goes by the method signature and only the synthetic bridge method has the signature that matches the one in the parent class after type erasure. I'm just writing this stuff as I think about it so excuse the flipflopping. The more I think about it though the more I tend to agree with the original guess that the polymorphic call goes through the synthetic bridge. The bridge would not be involved if binding happens statically to the subclass method with the specific type.
Another thing to consider is that a ClassCastException will be thrown at runtime. That would be happening in the synthetic method, which I guess would be the result of static binding(?). Anyway, I haven't tried any of this myself but you might try throwing a runtime exception somewhere strategic so you can look at the stack trace and see if the synthetic method was involved in the call. You'll probably have to put the throw inside an if statement that checks a non-final variable in its condition so your code will compile.
Rajdeep, I haven't looked into your example deeply but on the surface, your code is different from what the compiler would provide in a synthetic method after type erasure so I doubt the same mechanisms are in play.