Just the other day, I was wondering: What is the most important Java API? And, which of the SE and EE APIs is the one that makes most of the Java ecosystem possible, and could not have just been recreated as a third-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 a 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 we'd directly need 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 auto-wired injection without reflection (“manually” doesn’t count, as it’s not auto-wiring)? 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 a huge open-source ecosystem, Java would have been more of a niche. Of course, that’s not the only factor – there are multiple things that the language designers and then the JVM implementors got right. And reflection is, I think, one of those things.
Yes, using reflection feels hacky. Reflection in the non-framework code that feels like the last kind of 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.