I do believe it’s better. With reflection you have to at runtime
- get the class of the object you’re calling a method on
- list its methods
- filter them by arity and type of the arguments
- filter them by visibility
- find the one that is left, invoke it through the reflection API
in the above cases each call to
.bar is unambiguous, the compiler can know which one it is, and emit byte code that calls it directly.
Also, what about scenarios where there are multiple concrete classes or interfaces?
When you create the wrapper you need to pick the class or interface you’re wrapping, only objects that are assignable to that type will be able to be used with those generated functions. If there’s an interface then you should prefer that over the concrete object.