The other day I was wondering – which is the most important Java API. Which of the SE and EE APIs is the one that makes most of the Java ecosystem possible and that could not have just been recreated as a 3rd party library.
And as you’ve probably guessed by the title – I think it’s the Reflection API. Yes, it’s inevitably part of every project, directly or indirectly. But that’s true for many more APIs, notably the Collection API. But what’s important about the Reflection API is that it enabled most of the popular tools and frameworks today – Spring, Hibernate, a ton of web frameworks.
Most of the other APIs can be implemented outside of the JDK. The Collections API could very well be commons-collect or guava. It’s better that it’s part of the JDK, but we could’ve managed without it (it appeared in Java 1.2). But the reflection API couldn’t. It had to almost be an integral part of the language.
Without reflection, you could not have any of the fancy tools that we use today. Not ORM, not dependency injection frameworks, and not most of the web frameworks. Well, technically, you could at some point have theme – using SPI, or using java-config only. One may argue that if it wasn’t for reflection, we’d have skipped the whole XML configuration era, and wend directly to code-based configuration. But it’s not just configuration that relies on reflection in all these frameworks. Even if Spring could have its beans instantiated during configuration and initialized by casting them to
InitalizingBean, how would you handle the autowired injection without reflection (“manually” doesn’t count, as it’s not autowiring)? In hibernate, the introspection and java bean APIs might seem sufficient, but when you dig deeper, they are not. And handling annotations would not be possible in general.
And without these frameworks, Java would not have been the widespread technology that it is today. If we did not have the huge open-source ecosystem, Java would have been rather niche . Of course, that’s not the only factor – there are multiple things that the language designers and then the JVM implementors got right. But reflection is, I think, one of those things.
Yes, using reflection feels hacky. Reflection in the non-framework code feels like a last resort thing – you only use it if a given library was not properly designed for extension but you need to tweak it a tiny bit to fit your case. But even if you have zero reflection code in your codebase, your project is likely full of it and would not have been possible without it.
The need to use reflection might be seen as one of the deficiencies of the language – you can’t do important stuff with what the language gives you, so you resort to a magic API that gives you unrestricted access to otherwise (allegedly) carefully designed APIs. But I’d say that even having reflection is a de-facto language feature. And it is one that probably played a key role in making Java so popular and widespread.