So, every Java text book talks about how flexible Java is since it can load classes at run time. Just cobble together a string and give it to Class.forName()
, and
It can be extremely useful in situations where you're using an API and the API designers actually deprecated some classes from one version to the next (for example the Contacts in Android).
Without reflection and dynamic class loading based on the string name, it would be impossible in this instance to have the same program run on both versions of the platform without getting a class not found exception at runtime. But with it, the same program was tweaked a bit and then could run on both platforms.
Any framework that is configuration based (struts, jsf, spring, hibernate, etc.) uses this mechanism. Any product that is based on the plugin architecture also uses this feature.
See the support for Oracle LOB handling in Spring Framework for example. Only because the framework offers specific support for Oracle you probably don't want to deploy an Oracle datasource as dependency for your e.g. MySQL projects. Therefore you load the Oracle drivers reflectively in the scope of an instance of the LOB handler.
Servlet containers like Tomcat read your war/webapp configuration file from WEB-INF/web.xml and load your Servlet/Filter/etc. subclasses based on the String values you put in the XML file. For database connections, they pull the class name to load from your configuration, e.g. "com.mysql.jdbc.Driver" for MySQL.
Real-world example (as requested in your question), proprietary application (as explicitely allowed by your question)...
Upon startup, the client-side software contacts our server(s) and says "Default implementation of interface Bar I have is Foo (because actually every version 1.03, for example, are using Foo), do you have a better one?" If meanwhile we wrote a better implementation, we answer "yup, Bar is old, use Buz, it's better".
Then on the client side a class loader is used to load the latest implementation.
It's oversimplified but it's a real world example. It's not entirely dissimilar to the example JRL mentioned: where deprecated classes are automagically replaced by newer ones.
I remember creating a class loader to load classes remotely. The application was running on one node while the classes were stored on another node.
And also by customising the class loader you can transform classes as they are loaded. This is used by some ORM frameworks as well as some AOP frameworks.