Why do I need to explicitly write Class.forName()

2019-08-17 13:04发布

问题:

This question already has an answer here:

  • Why do I need to call Class.forName in Tomcat Web Application even if I use a JDBC Driver 4.0? 1 answer

I have seen a lot of answers in stackoverflow say that

Pre Java 6 the DriverManager class wouldn't have known which JDBC driver you wanted to use. Class.forName("...") was a way on pre-loading the driver classes. If you are using Java 6 you no longer need to do this.

I am using Oracle12c database and JDK 8 with latest version of eclipse and tomcat for my web application. Also latest ojdbc7.jar and servlet-api.jar are added to build path.

Here's my servlet code:

public class NewServlet extends HttpServlet {
private static final long serialVersionUID = 102831973239L  ;

public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

        Connection con;
        try {
            con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","system","kiran12c");
            Statement stmt = con.createStatement();
            stmt.executeQuery("create table SpinCart_Customers1(cid number,cname varchar2(20))");
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

}

But when I run my servlet which creates a table in my database, I am getting the following error in console:

java.sql.SQLException: No suitable driver found for jdbc:oracle:thin:@localhost:1521:orcl

If I add the following code it is working fine (table successfully created).

try{
    Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch(java.lang.ClassNotFoundException e)
{
    e.printStackTrace();
}

Why is this happening? I am using jdk8, why do I still need to use Class.forname()?

回答1:

Class.forName("X") actually does one thing: it tells the classloader to search the classpath for class X and try to load it. As a side effect, any static initializers in class get their chance to run. This happens only when JVM first encounters class X. The same thing happens when one of your classes references class X as an import, except that in Class.forName("X") X does not have to be present at compile-time.

JDBC vendors typically use static initializers to register their driver with JDBC driver manager. Without it, DriverManager is not aware that provider is available, and cannot return a Connection. (In most cases, you can still bypass DriverManager and use fully qualified vendor classes directly, but that couples your code to specific vendor.) Registering a driver with Class.forName() is vendor-specific and not strictly mandated by JDBC. In any case, you should follow the vendor's instructions, because only they can tell you how their driver is supposed to be used.



标签: java oracle jdbc