Here, instantiation is dynamic because the parameter is a String that can be any JDBC database engine driver. In theory, you could switch database engines merely by changing the value of the parameter.
I had a real hard time getting the dynamic instantiation working in the one line of code above.
After spending a great deal of time trying to get the example code working, thinking that my database engine wasn't installed properly, I tried the following line of code:
To use the "new" operator, you can't even compile unless the class that you're instantiating is findable.
The above line of code above worked. It's much simpler.
Once I got the "new" operator working, then I could turn my attention toward generalizing the code by making the class name to be instantiated a parameter as in the original example.
objects are never created at compile time. How could they be? I can compile my code on machine 'A', then send the class files over the sneakernet to machine 'B'. That machine can run the code, without ever knowing anything about 'A'.
There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors
I think the compilation difference you're looking for is this: With class.forName(String).newInstance() your class doesn't actually have to exist at compile time. However, if the jre doesn't find it at run time, your code will throw a NoClassDefFoundException. With the new operator, your class will not even compile, if it can not be found.
Another difference is that by using new you can call different constructors in the class you're instantiating. And by using Class.newInstance() you're only able to call the no-args constructor of that class. However, there is a way to instantiate objects dinamically and by calling any constructor of that object's class. For example, if you want to call a (String) constructor: