为什么在使用JDK 8时需要显式编写Class.forName()?

时间:2017-10-09 18:34:06

标签: java oracle jdbc

我在stackoverflow中看到很多答案都说

  

Pre Java 6,DriverManager类不知道您要使用哪个JDBC驱动程序。 Class.forName(“...”)是一种预加载驱动程序类的方法。   如果您使用的是Java 6,则不再需要这样做。

我正在使用Oracle12c数据库和JDK 8以及最新版本的eclipse和tomcat用于我的Web应用程序。最新的ojdbc7.jar和servlet-api.jar也被添加到构建路径中。

这是我的servlet代码:

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();
        }

}

但是当我运行在我的数据库中创建表的servlet时,我在控制台中收到以下错误:

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

如果我添加以下代码,它工作正常(表已成功创建)。

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

为什么会这样?我使用的是jdk8,为什么还需要使用Class.forname()

1 个答案:

答案 0 :(得分:0)

Class.forName(“X”)实际上做了一件事:它告诉类加载器在类路径中搜索类X并尝试加载它。作为副作用,类中的任何静态初始化器都有机会运行。只有当JVM第一次遇到类X时才会发生这种情况。当你的一个类引用类X作为导入时会发生同样的事情,除了在Class.forName(“X”)中X不必在编译时出现。 / p>

JDBC供应商通常使用静态初始化程序向JDBC驱动程序管理器注册其驱动程序。没有它,DriverManager不知道提供程序可用,并且无法返回Connection。 (在大多数情况下,您仍然可以绕过DriverManager并直接使用完全限定的供应商类,但这会将您的代码与特定供应商联系起来。)使用Class.forName()注册驱动程序是特定于供应商的,而不是JDBC严格规定的。在任何情况下,您都应该遵循供应商的指示,因为只有他们可以告诉您如何使用他们的驱动程序。