import 和 class.forName 都加载类文件。当我在jsp文件中导入mysql数据的示例时,需要通过class.forName导入驱动类。当我通过import语句导入jdbc驱动时,它无法从tomcat服务器中的mysql获取数据。
7 回答
1 : import
==> loads the class when you call any instance of it or call anything by class reference
==> loads the class when call is made
2 : Class.forName("");
==> loads the class in the jvm immediately
如果一个类有静态块可以看出差异
==> import will not call the static block
==> Class.forName("") will call the static block
在你的情况下
===> Driver class when loaded by Class.forName("") , executes its static block , which published the driver
==> Simply importing the Driver class wont execute the static block and thus your Driver will not be published for connection objects to be created
class.forName
允许您使用 Driver 类而无需为您的类显式导入。这使您无需在类路径中包含 jdbc 驱动程序即可构建项目。
以及“它无法从 mysql 获取数据”的原因,因为您可能没有返回对有关 jdbc 驱动程序类的变量的引用。
希望能帮助到你..
Driver 类被加载,因此通过调用 Class.forName 方法自动注册到 DriverManager。这会显式加载驱动程序类。由于它不依赖于任何外部设置,因此这种加载驱动程序的方式是使用 DriverManager 框架的推荐方式。以下代码加载类 acme.db.Driver:
Class.forName("acme.db.Driver");
如果 acme.db.Driver 已被编写,以便加载它会导致创建一个实例并使用该实例作为参数调用 DriverManager.registerDriver(应该这样做),那么它位于 DriverManager 的驱动程序列表中并且可用于创建连接。
从这个答案中挑选出来。阅读它以获取详细信息。但我猜import 不会在 driver manager 下注册驱动程序。
- import
当一个以短名称使用的类即将被 JVM 加载时,“import”短语会告诉类加载器在哪里找到该类。所以“import”不加载任何类,它只是定义类的位置。 - Class.forName()
立即加载并初始化一个类到 JVM。
BYW:加载类的 3 种方法。
1)使用“new”关键字(加载类+初始化类+新实例)
Dog d = new Dog();
2)使用“Class.forName()”(加载类+初始化类)
Class dogClass = Class.forName("Dog")
3)使用“classLoader.loadClass()”(加载类)
来自文档类#forName
public static Class<?> forName(String className)
throws ClassNotFoundException
返回与具有给定字符串名称的类或接口关联的 Class 对象。调用此方法等效于:
Class.forName(className, true, currentLoader)
其中currentLoader
表示当前类的定义类加载器。
例如,以下代码片段返回名为 的类的运行时类描述符java.lang.Thread
:
Class t = Class.forName("java.lang.Thread")
调用 会forName("X")
导致初始化名为 X 的类。
来自语言规范jls-7.5
导入声明使类型或成员仅在实际包含导入声明的编译单元中通过其简单名称可用。
另一种不太常见的导入形式允许您导入封闭类的公共嵌套类。
Java 中的“import”语句允许您访问使用您很重要的类或资源。
例如:
import my.package.Utils;
现在,我可以在我正在工作的当前类中访问我的 Utils 类:
import my.package.Utils;
public static void main(String[] args) {
Utils.doStuff(); //I can do this because I have access to Utils in my import
}
Class.forName 动态加载一个类。这在类可能发生变化的情况下很有用,例如 SQL 驱动程序实现。JDBC 在编译时不知道要导入哪个类。
调用 Class.forName 将不允许您在当前正在使用的整个类中访问它,全局导入语句会这样做。
使用 JDBC,我们可以使用抽象类,例如java.sql.DataSource
定义数据库的类。但是,MySQL 数据源和 Microsoft SQL 数据源是不同的实现。JDBC 不知道您要使用哪一个。
因此,您使用 DriverManager 向 JDBC 指定您要使用 MySQL 实现,然后加载该驱动程序的类。
稍后说您切换到 Microsoft SQL。现在,您所要做的就是更改 DriverManager 以加载 Microsoft SQL 驱动程序的类,所有使用抽象java.sql
类的代码仍然可以工作。
由于您添加了 jdbc 标签,因此我将对此进行回答。
正如 Hussain Akhtar Wahid 所说,Class.forName("name");
调用静态初始化器
java 通过 DriverManager 处理许多 SQL 驱动程序,而不是为每个驱动程序编写代码,您只需要注册该驱动程序并DriverManger
为您完成工作。
java.mysql.jdbc.Driver 类中的静态初始化程序
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
您通过调用所做的Class.forName("com.mysql.jdbc.Driver");
是注册 DriverManger 告诉我要访问 mysql 数据库。
片段来源