Class.forName() 是什么意思?

3

我在学习JDBC,唯一不明白的是以下代码中的Class类。

无论我是否删除Class.forName("com.mysql.jdbc.Driver"),它都能正常工作。

你能解释一下这部分中的Class.forName("com.mysql.jdbc.Driver")函数是什么作用吗?

import java.sql.*;
public class JSP {

    public static void main(String[] args){
        Connection myConn = null;
        Statement st= null;
        ResultSet rs= null;

        try {
            Class.forName("com.mysql.jdbc.Driver");
            myConn = DriverManager.getConnection("jdbc:mysql://localhost:3306/customer", "root", "Gspot");

            st = myConn.createStatement();
            String query = "select * from customers";

            rs = st.executeQuery(query);
            while(rs.next()){
                System.out.println(rs.getString("name"));
            }
        } catch(SQLException e){
            e.printStackTrace();
        } catch(ClassNotFoundException e) {
            System.out.println("wow");
        }
    }
}

http://www.xyzws.com/javafaq/what-does-classforname-method-do/17 - Nagaraju Badaeni
JDBC 4不需要使用这个技巧就可以工作,它使用清单中的服务来查找这些类,因此您不需要它。 - Peter Lawrey
4个回答

9

Class.forName方法创建一个与给定名称对应的java.lang.Class实例。这会强制类加载器加载该类,并执行其中的任何static代码块。

旧版本的JDBC驱动程序使用这些静态块向java.sql.DriverManager注册自己,以便稍后用于连接到数据库。Java 6中的JDBC 4引入了一种机制来自动加载JDBC驱动程序,因此不再需要这样做。


5

Class.forName("com.mysql.jdbc.Driver")通过反射获取指定类的类对象。

如果这个类已经存在,那么在代码中有没有这行代码是没有区别的,因为你没有对返回值做任何操作。但是,如果这个类不存在于类路径中,你会从该调用中得到一个异常,因此你会知道驱动程序缺失而不是连接失败。

假设MySQL驱动程序不在类路径上。

如果没有这个语句,你可能会收到一个像“无法打开连接”的错误,并且你可能需要解析日志并查找原因。

如果调用了这个语句,你就会得到一个ClassNotFoundException,你就会知道问题的原因:类加载器没有找到驱动程序类。

编辑:阅读@Mureinik的答案,那可能是更好的理由。 :)


2
我建议您阅读这篇论文:了解Java中的Class.forName() 如果您调用Class.forName("com.mysql.jdbc.Driver");,则驱动程序类com.mysql.jdbc.Driver将被加载到内存中。每个这样的驱动程序类都有以下静态块:
static {
    try {
         java.sql.DriverManager.registerDriver(new Driver());
     } catch (SQLException E) {
         throw new RuntimeException("Can't register driver!");
     }
}

如果你正在加载这个类,静态代码块会自动调用并注册驱动程序(如果成功)。


1
根据文档 (http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#forName(java.lang.String)) :
调用 forName("X") 会导致名为 X 的类被初始化。
这意味着该类从磁盘加载,且其静态初始化器被调用,例如:
public class Test {
    private static final int a;    
    static { // called when the class is loaded via forName or any other loading mechanism
        a = 5;
        doSomething(a);
    }
    private static int doSomething(int x) {
        return (x+5);
    }
}

这只会在类加载时发生一次。例如在您的情况下,我们可以假设它允许驱动程序运行代码以将自己注册到JDBC中。

如果省略此调用不会改变运行时行为,则意味着该类已经被加载过了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接