【问题标题】:What does it mean Class.forName() [duplicate]这是什么意思 Class.forName() [重复]
【发布时间】:2015-01-04 00:52:45
【问题描述】:

我正在学习 JDBC,唯一我没有得到的是下面代码中的类。

无论我删除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");
        }
    }
}

【问题讨论】:

标签: java mysql class jdbc


【解决方案1】:

我推荐你阅读这篇论文:Understanding-ClassforName-Java

如果您调用Class.forName("com.mysql.jdbc.Driver");,驱动程序类com.mysql.jdbc.Driver 将被加载到内存中。每个这样的 Driver 类都有这样的静态块:

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

因此,如果您正在加载类,静态块将被自动调用,驱动程序将被注册(如果成功)。

【讨论】:

    【解决方案2】:

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

    如果该类存在,则在代码中是否包含该行没有区别,您不会对返回值做任何事情。但是,如果它在类路径中不存在,您会从该调用中得到一个异常,因此您会知道驱动程序丢失而不是连接失败。

    假设 MySQL 驱动程序不存在于类路径中。

    如果没有该语句,您可能会出现“无法打开连接”之类的错误,您可能需要解析日志并查找原因。

    如果调用该语句,您会得到一个ClassNotFoundException,因此您会知道问题的原因:类加载器找不到驱动程序类。

    编辑:阅读@Mureinik 的回答,这可能是该声明的更好理由。 :)

    【讨论】:

      【解决方案3】:

      根据文档 (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。

      如果为您省略此调用不会改变运行时行为,则表示该类之前已加载。

      【讨论】:

        【解决方案4】:

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

        旧的 JDBC 驱动程序过去使用这些静态块将自己注册到java.sql.DriverManager,以便以后可以用来连接到数据库。 JDBC 4 是 Java 6 的一部分,引入了一种自动加载 JDBC 驱动程序的机制,因此不再需要。

        【讨论】:

          猜你喜欢
          • 2011-10-08
          • 2017-06-30
          • 2011-10-09
          • 2020-09-01
          • 1970-01-01
          • 2016-10-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多