I guess I follow the technical reason that the interface doesn’t override the method so there can’t be a specialized version of it. But that’s only visible through reflection right? Not in the direct language semantics?
I guess I follow the technical reason that the interface doesn’t override the method so there can’t be a specialized version of it. But that’s only visible through reflection right? Not in the direct language semantics?
I think that your misunderstanding comes from the fact that you base your understanding in Java semantics, but we really need to deal with the JVM's semantics. Your suggestion only makes sense when:
a) All of the typing information is preserved across a whole build b) The build is entirely static, no new classes can be loaded
Both of these are at odds with how the JVM functions. First: We lose type parameters on compilation, so we only see that Frobber extends Fun, the type parameters are lost and its usages are converted to Object.
Second: The JVM loads code by lazily loading classfiles. All classfiles are independent, and more can be added to a system.
Would including the specialized method in the derived interface bytecode preemptively take us all the way to C++ templates and ruin everything that’s good about Java? Or is it a matter of type erasure being consistently applied and if it were ignored selectively it would make everything more confusing?
Like if we had final class Foo implements Func<…> then we’d presumably need to supply a typed implementation of apply, so the fact that we can get away with the generic one in a specialized interface feels surprising, even though I can see why it’s technically correct.