【问题标题】:Why we call Class.forname("com.mysql.jdbc.Driver") even if mysql.jar is added in class path为什么我们调用 Class.forname("com.mysql.jdbc.Driver") 即使在类路径中添加了 mysql.jar
【发布时间】:2014-01-18 09:53:43
【问题描述】:

为什么我们调用 Class.forname("com.mysql.jdbc.Driver") 即使 mysql.jar 被添加到类路径中。我认为 System ClassLoader 也应该加载这个类,如果没有那么任何主体都可以描述如何定义的Driver写成在加载类路径中的类时不加载?

【问题讨论】:

标签: java mysql jdbc


【解决方案1】:

它在旧 Java 版本中用于 DriverManager 了解可用的 JDBC 驱动程序。现在不需要使用它,尤其是当您明确给出驱动程序类名称时。

【讨论】:

    【解决方案2】:

    无需从具有 JDBC 4 的 Java 7 调用 Class.forname("com.mysql.jdbc.Driver")

    【讨论】:

    【解决方案3】:

    您可以在此处阅读:What is the actual use of Class.forName("oracle.jdbc.driver.OracleDriver") while connecting to a database? .. 驱动程序可能不同.. 概念保持不变。

    【讨论】:

      【解决方案4】:

      DriverManager 了解可用的 JDBC 驱动程序的旧 Java 版本,这不是必需的。

      Class.forName("X") 的调用会导致名为X 的类被动态加载(在运行时)。调用 forName("X") 会导致初始化名为 X 的类(即,JVM 在类加载后执行其所有静态块)。 Class.forName("X") 返回与“X”类关联的 Class 对象。返回的 Class 对象不是“x”类本身的实例。

      Class.forName("X") 加载尚未加载的类。 JVM 会跟踪以前加载的所有类。此方法使用调用它的类的类加载器。 “X”是所需类的完全限定名。

      JDBC Driver Is a Good Example
      

      您可能有使用 JDBC 驱动程序的经验。例如,类加载器尝试加载和链接“org.gjt.mm.mysql”包中的驱动程序类。如果成功,则调用静态初始化程序。

      Class.forName("org.gjt.mm.mysql.Driver");
      Connection con = DriverManager.getConnection(url,?myLogin", "myPassword");
      

      【讨论】:

        【解决方案5】:

        查看 Driver 类的定义,它在静态块中注册 Driver 并实例化 Driver 类,当类加载到 JVM 时调用该静态块

        public class Driver extends NonRegisteringDriver implements java.sql.Driver {
            static {
                try {
                    java.sql.DriverManager.registerDriver(new Driver());
                } catch (SQLException E) {
                    throw new RuntimeException("Can't register driver!");
                }
            }
        public Driver() throws SQLException {
                // Required for Class.forName().newInstance()
            }
        }
        

        如果我们写

            Driver dr=new Driver();
                Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/massiverun","root","admin");
                System.out.println("Print"+con);
        

        然后类 Driver 将被实例化两次,并且静态块将被调用 当调用 new Driver() 时。如果我们使用 Class.forname("com.mysql.jdbc.Driver") 代替 new Driver() 驱动程序类被实例化一次,如果类已经加载到 JVM 静态块中,则不会第二次调用。

        【讨论】:

          猜你喜欢
          • 2015-12-31
          • 2014-04-25
          • 1970-01-01
          • 2015-12-12
          • 1970-01-01
          • 2013-10-25
          • 1970-01-01
          • 1970-01-01
          • 2012-07-01
          相关资源
          最近更新 更多