Java 更好地理解-Class.forName(";com.mysql.jdbc.Driver";).newInstance();
我遇到了这样一个问题:当更新到攻击我的web服务器时,它可以完美地工作。我什么都能做 现在,我唯一不完全理解的是Java 更好地理解-Class.forName(";com.mysql.jdbc.Driver";).newInstance();,java,mysql,Java,Mysql,我遇到了这样一个问题:当更新到攻击我的web服务器时,它可以完美地工作。我什么都能做 现在,我唯一不完全理解的是类.forName() 为什么要用这个?这能做得不同吗?这是不是为了别的什么?添加引用?创建一个类作为实现/扩展另一个类 我想完全理解正在发生的事情,但这是我的方式 谢谢代码正在强制表示MySQL驱动程序的类加载和初始化。在Java中,除非必须加载类,否则不会加载该类。由于JDBC代码通常从不直接引用驱动程序,因此如果没有Class.forName(或其他等效选项),就无法加载该驱动程
类.forName()
为什么要用这个?这能做得不同吗?这是不是为了别的什么?添加引用?创建一个类作为实现/扩展另一个类
我想完全理解正在发生的事情,但这是我的方式
谢谢代码正在强制表示MySQL驱动程序的类加载和初始化。在Java中,除非必须加载类,否则不会加载该类。由于JDBC代码通常从不直接引用驱动程序,因此如果没有
Class.forName
(或其他等效选项),就无法加载该驱动程序
请注意,必须同时加载和初始化类,这是两件不同的事情
另外,请注意,不需要调用.newInstance()
——驱动程序的静态初始值设定项已经将自己注册为JDBC驱动程序
最后,请注意,使用服务加载程序API通常不需要调用Class.forName()来加载驱动程序:它可以自动加载。您可以使用以下示例:
import com.mysql.jdbc.Driver;
public class MyClass {
//[...]
public void myMethod() {
Class<Driver> clz = Driver.class;
Driver driver = clz.newInstance();
}
}
导入com.mysql.jdbc.Driver;
公共类MyClass{
//[...]
公共方法(){
Class clz=Driver.Class;
Driver-Driver=clz.newInstance();
}
}
但这并不是那么灵活;例如,您可以从配置文件中读取名称“com.mysql.jdbc.Driver”。可能您想使用其他驱动程序(来自Oracle),但不想更改代码;按照上面介绍的方式,这是不可能的,因此正确的方法是使用
类。forName(name)
所有JDBC驱动程序都有一个向DriverManager注册自身的静态块,而DriverManager只有一个静态初始值设定项
MySQL JDBC驱动程序有一个静态初始值设定项,如下所示:
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
JVM执行静态块,驱动程序向DriverManager注册自身。
您需要一个数据库连接来操作数据库。为了创建到数据库的连接,DriverManager类必须知道要使用哪个数据库驱动程序。它通过迭代已注册的驱动程序数组(内部为向量),并对数组中的每个驱动程序调用acceptsURL(url)方法,有效地要求驱动程序告诉它是否可以处理JDBC url。Class.forName(className)
使用指定的类名加载类
JDBC驱动程序以这种方式加载,以避免编译时依赖于特定的JDBC驱动程序。其思想是使用Java的JDBCAPI(包Java.sql
和javax.sql
中定义的类和接口),而不必直接引用特定的JDBC驱动程序
当使用forName
调用让Java加载驱动程序类时,驱动程序将注册自身以便使用
注意,对于大多数JDBC驱动程序,没有必要显式地创建驱动程序类的新实例;您可以停止调用.newInstance()
请注意,自JDBC版本4.0以来,不再需要调用Class.forName()
调用-发现驱动程序的过程已经改进,JDBC可以自动加载它们。您是否查看了方法forName()的API文档
在classjava.lang.class
中?那么这可以在表示代码中的驱动程序的多个类上连续调用,而不会产生我假设的后果?但为什么要这样做呢?我想这是我真正的问题。是否有更持久的方法(在项目中添加引用等)来执行此操作?您必须向库中添加引用才能执行此操作。这样做是为了将驱动程序与代码解耦,因为假设您以后可能要替换数据库和驱动程序。有关类加载/初始化的更多信息,请选中以添加实际需要的。newInstance()
,因为某些JDBC驱动程序不符合规范,并且不在静态初始化期间注册自己,而是在实例化期间注册自己。关于“通常不需要调用Class.forName”这一事实:如果您使用的是JDBC 4或4.1,那么驱动程序供应商正确地完成了它的工作,就没有必要这样做。如果您使用的是JDBC3,或者供应商没有在META-INF/services/java.sql.Driver
中提供驱动程序的类名,则必须使用此选项。