What is the difference between "Class.forName()" and "Class.forName().newInstance()"?
When you call Class.forName(String className)
, it loads the class but does not instantiate it. This is essentially window shopping—you're inspecturing the class, causing static initialization blocks to be executed if present.
When you invoke Class.forName(String className).newInstance()
, it's the equivalent of purchasing what you window shopped. It not only loads the class into memory but also creates an instance using the no-arg constructor.
Best Practice (since Java 9):
Note: .newInstance()
is deprecated, advising to lean into the above pattern which enables better exception handling.
Loading versus Instantiating
Class.forName()
initiates the class loading process, which includes verifying, preparing, resolving, and initializing the class. It's crucial for JDBC to run the static initialization blocks, which register drivers.
newInstance()
, however, doesn't stop at just loading. It creates a new instance of the class, thanks to the sweet no-arg constructor.
Application-wise Decision
If you're interested to interact just with static members and avoid the overhead of creating an instance, go with Class.forName()
.
Thanks to automated driver registration in JDBC 4.0 and up, casually using Class.forName().newInstance()
for registering drivers is becoming a tale of yore.
Tread Carefully
Don't blindly rely on newInstance()
as you'll stumble over InstantiationException
if your class lacks a public no-arg constructor. Additionally, lurking security restrictions can cause IllegalAccessException
. Hence, the ideal approach is getDeclaredConstructor().newInstance()
that aids detailed exception handling.
Digging Legacy Code
Even newInstance()
might be deprecated, but real programmers know its value in the legacy code maintenance. The more recent mechanisms offer both expressive and safer ways to escape the typical pitfalls.
Adapting with Java
Growing with Java, the widespread use of factory patterns and dependency injection has nudged Class.forName().newInstance()
to the sidelines. With smarter options like Service Loader APIs or Spring's BeanFactory, we've evolved to a more structured and modular approach.
Performance Reality
Before drowning in the charm of reflection, be prepared for its performance hit. The class loading and instantiation via reflection use more resources and take longer than their static counterparts. Compile-time checks? You can kiss them goodnight, as runtime checks take the throne, potentially hurling runtime errors.
Was this article helpful?