Downsides of reflection in general
Reflection is harder to understand than straight-line code.
In my experience, reflection is an "expert-level" feature in Java. I would argue that most programmers never use reflection actively (i.e. consuming libraries that use reflection doesn't count). That makes code using it harder to understand for these programmers.
Reflection code is inaccessible to static analysis
Suppose I have a getter getFoo
in my class and I want to rename it to getBar
. If I use no reflection, I can just search the code base for getFoo
and will find every place that uses the getter so I can update it, and even if I miss one, the compiler will complain.
But if the place that uses the getter is something like callGetter("Foo")
and callGetter
does getClass().getMethod("get"+name).invoke(this)
, then the above method won't find it, and the compiler won't complain. Only when the code is actually executed will you get a NoSuchMethodException
. And imagine the pain you're in if that exception (which is tracked) is swallowed by callGetter
because "it's only used with hard-coded strings, it can't actually happen". (Nobody would do that, someone might argue? Except that the OP did exactly that in his SO answer. If the field is renamed, users of the generic setter would never notice, except for the extremely obscure bug of the setter silently doing nothing. Users of the getter might, if they're lucky, notice the console output of the ignored exception.)
Reflection code is not type-checked by the compiler
This is basically a big sub-point of the above. Reflection code is all about Object
. Types are checked at runtime. Errors are discovered by unit tests, but only if you have coverage. ("It's just a getter, I don't need to test it.") Basically, you lose the advantage using Java over Python gained you in the first place.
Reflection code is unavailable for optimization
Maybe not in theory, but in practice, you won't find a JVM that inlines or creates an inline cache for Method.invoke
. Normal method calls are available for such optimizations. That makes them a lot faster.
Reflection code is just slow in general
The dynamic method lookup and type checking necessary for reflection code is slower than normal method calls. If you turn that cheap one-line getter into a reflection beast, you might (I have not measured this) be looking at several orders of magnitude of slowdown.
Downside of generic getter/setter specifically
That's just a bad idea, because your class now has no encapsulation anymore. Every field it has is accessible. You might as well make them all public.
Map
'sget
andput
, which is a pretty clunky way of doing things.