2

In the example below showing how to use Java's SQL library, Class.forName() is called without a variable to save a reference to the object. What is the purpose of doing this if you cannot manipulate it later? I've seen that line written in various examples of the SQL library.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Sample
{
  public static void main(String[] args) throws ClassNotFoundException
  {
    // load the sqlite-JDBC driver using the current class loader
    Class.forName("org.sqlite.JDBC");

    Connection connection = null;
    try
    {
      // create a database connection
      connection = DriverManager.getConnection("jdbc:sqlite:sample.db");
      Statement statement = connection.createStatement();
      statement.setQueryTimeout(30);  // set timeout to 30 sec.

      statement.executeUpdate("drop table if exists person");
      statement.executeUpdate("create table person (id integer, name string)");
      statement.executeUpdate("insert into person values(1, 'leo')");
      statement.executeUpdate("insert into person values(2, 'yui')");
      ResultSet rs = statement.executeQuery("select * from person");
      while(rs.next())
      {
        // read the result set
        System.out.println("name = " + rs.getString("name"));
        System.out.println("id = " + rs.getInt("id"));
      }
    }
    catch(SQLException e)
    {
      // if the error message is "out of memory", 
      // it probably means no database file is found
      System.err.println(e.getMessage());
    }
    finally
    {
      try
      {
        if(connection != null)
          connection.close();
      }
      catch(SQLException e)
      {
        // connection close failed.
        System.err.println(e);
      }
    }
  }
}
informatik01
  • 16,038
  • 10
  • 74
  • 104
Orca Ninja
  • 823
  • 1
  • 15
  • 29
  • It will make the classloader to load the Driver class implementation in the DriverManager of the class pointing to the library that implements the JDBC so you can easily use JDBC through interfaces instead of using direct implementations. – Luiggi Mendoza Jul 04 '13 at 20:34
  • 1
    As an addition, read [this thread](http://stackoverflow.com/questions/2092659/what-is-difference-between-class-forname-and-class-forname-newinstance). It has both the discussion of `Class.forName()` and JDBC. – informatik01 Jul 04 '13 at 20:46
  • 1
    BalusC 's answer in the thread which @informatik01 mentioned is the right answer, very clear. +1 – Joe.wang Apr 05 '20 at 13:54

1 Answers1

3

It makes the class initializer run - which in the case of JDBC drivers used to be the way that the driver would register itself with DriverManager. In modern Java, JDBC drivers are usually found using the service provider API.

From the docs:

Applications no longer need to explictly load JDBC drivers using Class.forName(). Existing programs which currently load JDBC drivers using Class.forName() will continue to work without modification.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Right. It causes the driver to be registered with the DriverManager framework, so that later when you use the DriverManager to use a connection it knows which JDBC driver to use for which connection schema. I think the modern alternative to using Class.forName("driver clas name") is: DriverManager.registerDriver(new org.sqlite.JDBC()); – Keith Jul 04 '13 at 20:38
  • 1
    @Keith: No, I believe the modern equivalent is to let the service provider API work it out for itself. You just specify the JDBC URL and it will find the driver. – Jon Skeet Jul 04 '13 at 20:39
  • Hmmm, thought experiment: So if I have 1000 JDBC drivers jars in my classpath, and I call DriverManager.getConnection(url). Is it, at that point, going to load classes from all 1000 jars, query them somehow to determine which is the correct to use? I just ran a simple test case, and without calling the regester line I got: No suitable driver found for jdbc:mysql://localhost:3306/db. – Keith Jul 04 '13 at 20:42
  • @Keith: That surprises me - it *should* have worked. I'll quote the relevant bit from the docs. – Jon Skeet Jul 04 '13 at 20:46
  • You are right. Updated my test case to use a new version of the JDBC driver, and now it does work, without calling registerDriver(). I guess newer JDBC driver jars have a standard resource/properties-file that maps schema to driver class-- or something like that. – Keith Jul 04 '13 at 20:49