Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Can someone explain Class.forName()???

Status
Not open for further replies.

musik

Programmer
Nov 20, 2001
33
US
I hope this isn't a total "newbie" question. I've searched everywhere (including here) and can't find a decent answer. I feel better that the Deitel Java book says that a discussion of Class.forName is "outside the scope of this book".

Here goes:

What does Class.forName(String) do?

O.K. I "know" the "answer" to that. It "loads" the class of name String and returns a Class object representing it. Fine. But what good is that? If I don't then proceed to call theClassObject.newInstance(), I won't have an actual instance will I? So what possible good has occurred? Have I got some bad blinders saying that "you must have a reference to an instance" for an object to be any use? (Of course, statics are another matter, but that's beside the point... or is it???)

As a corollary, why do you have to do a Class.forName("jdbc.driver.of.your.choice"); in every JDBC app? What good does it do? We're not actually creating an instance of the driver, we're just "loading" it. What??? We're not even storing a reference to the Class object that got created. Doesn't that mean it just goes immediately to the garbage collection queue?

I'm totally befuddled.

Thanks in advance! This has been frustrating me for a while!

-DG
 
The reason why JDBC uses Class.forName("driver.class.name"); is down to how Sun designed the java.sql.DriverManager class. This class handles loading the actual drivers ready for reaping connection objects. All Drivers call DriverManager.registerDriver(), and then when getConnection() is called, the DriverManager loops through the the registered drivers and attempts to match one with the specified db URL. Now its not actually necessary to use Class.forName() but the reason people do is that just one class can service many databases for retrieving connections by passing in the driver class name, and url at runtime.

So to clarify, when CLass.forName() is called, no an Object is not created but the code that registers the driver is loaded - below is the MySQL com.mysql.jdbc.Driver code that does this :

Code:
    static {
        try {
            java.sql.DriverManager.registerDriver(new Driver());
        } catch (java.sql.SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }

        if (DEBUG) {
            Debug.trace("ALL");
        }
    }

and here is the java.sql.DriverManager code that registers the driver :

Code:
    public static synchronized void registerDriver(java.sql.Driver driver)
	throws SQLException {
	if (!initialized) {
	    initialize();
	}
      
	DriverInfo di = new DriverInfo();
	di.driver = driver;
	di.driverClass = driver.getClass();
	di.driverClassName = di.driverClass.getName();
	drivers.addElement(di);
	println("registerDriver: " + di);
    }

Class.forName() is also used in reflection for invoking methods without instantiating a new class. One can extract the methods available in a class using

Method[] m = class.getDeclaredMethods();

and then you can invoke the method using the

m.invoke();

 
O.K... I think I'm almost with you. So is there a static method on jdbc driver classes that is getting called when Class.forName() loads the driver? (I read somewhere that Class.forName() "initialises" the class. Does this mean it's looking for some static "init" method or something?) I'm still not sure how the DriverManager "knows" that a driver has been "loaded". A better way to put it is, what code from where is actually _calling_ DriverManager.registerDriver()? (My hypothetical public static void init()?) This certainly doesn't happen on _every_ call to Class.forName() since you could be using it to do reflection on _any_ class, right?

OH! OK. WAIT! STOP. Sorry! I just answered my own question. Yes, there IS some static code that is being run "on load", just not a "method". I just didn't realise that that was what you were showing me in your post (I thought that block must've been _inside_ a method) until I looked at the source for org.hsqldb.jdbcDriver. I've never seen a block of code declared static at the top level inside a class... didn't realise it was possible, though know that I think about it, it seems obvious. How _totally_ cool! Are there any other places where this technique is commonly used? Is there an official name for this "static method with no signature" block?
 
Found it. In Java in a Nutshell, 4th ed., David Flanagan, O'Reilly & Assoc., Inc., page 97:

------------------------------------------------------------
Initializer blocks

...Java does allow us to write arbitrary code for the initialization of class fields... with a construct known as a static initializer. A static initializer is simply the keyword [tt]static[/tt] followed by a block of code in curly braces.

------------------------------------------------------------
Thanks again, sedj, for pointing me in the right direction on this one!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top