java中import和class.forName的区别

Posted

技术标签:

【中文标题】java中import和class.forName的区别【英文标题】:Difference Between import and class.forName in java 【发布时间】:2013-11-09 14:00:43 【问题描述】:

import 和 class.forName 都加载类文件。 当我做一个在jsp文件中导入mysql数据的例子时,需要通过class.forName导入驱动类。当我通过import语句导入jdbc驱动时,它无法从tomcat服务器中的mysql获取数据。

【问题讨论】:

从 Java 7 开始,您甚至不必这样做。它将自动从您的课程路径中获取。 我用的是java 6。请说说区别.. 如果我理解正确,导入是在编译时处理的,而 class.forName 是在运行时处理的。 因为我是jdbc的起步阶段,能不能用例子简单解释一下。 这可能对xyzws.com/Javafaq/what-does-classforname-method-do/17有帮助 【参考方案1】:
    导入 当一个以短名称使用的类即将被 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()”(加载类)

【讨论】:

【参考方案2】:

既然你添加了 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 数据库。

sn-psource

【讨论】:

【参考方案3】:

来自 docsClass#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

导入声明使类型或成员仅在实际包含导入声明的编译单元中通过其简单名称可用。

另一种不太常见的导入形式允许您导入封闭类的公共嵌套类。

【讨论】:

【参考方案4】:

class.forName 允许您使用 Driver 类,而无需为您的类显式导入。这使您无需在类路径中包含 jdbc 驱动程序即可构建项目。

以及“它无法从 mysql 获取数据”的原因,因为您可能没有返回对有关 jdbc 驱动程序类的变量的引用..

希望对你有帮助..

【讨论】:

【参考方案5】:

Driver 类被加载,因此通过调用 Class.forName 方法自动注册到 DriverManager。这会显式加载驱动程序类。由于它不依赖于任何外部设置,因此这种加载驱动程序的方式是使用 DriverManager 框架的推荐方式。以下代码加载类 acme.db.Driver:

Class.forName("acme.db.Driver");

如果 acme.db.Driver 已被编写为加载它会导致创建一个实例,并使用该实例作为参数调用 DriverManager.registerDriver(应该这样做),那么它在 DriverManager 的驱动程序列表中并可用于创建连接。

从this 回答。阅读它以获取详细信息。但我猜import不会在驱动管理器下注册驱动

【讨论】:

【参考方案6】:

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 将不允许您在当前工作的整个班级中访问它,而全局 import 语句会这样做。

通过 JDBC,我们可以使用抽象类,例如 java.sql.DataSource,它定义了一个数据库。但是,MySQL 数据源和 Microsoft SQL 数据源是不同的实现。 JDBC 不知道你要使用哪一个。

因此,您使用 DriverManager 向 JDBC 指定要使用 MySQL 实现,然后加载该驱动程序的类。

稍后说明您切换到 Microsoft SQL。现在,您只需更改 DriverManager 以加载 Microsoft SQL 驱动程序的类,所有使用抽象 java.sql 类的代码仍然可以工作。

【讨论】:

当我用一个主类测试我的 mysql 检索 java 程序时。那时不需要class.forname,我只是通过import语句导入jdbc驱动类。只有在tomcat服务器调用jsp页面时才需要class.forname。【参考方案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

【讨论】:

当我用一个主类测试我的 mysql 检索 java 程序时。那时不需要class.forname,我只是通过import语句导入jdbc驱动类。只有在tomcat服务器调用jsp页面时才需要class.forname。 能否请您发布您的核心 java 程序中的代码,您是如何创建连接对象的? 看到这个link 我像 import com.mysql.jdbc.Driver 一样导入;当我使用主类 java 程序进行测试时,它可以工作。 这里有一个在 youtube 上解释得很好的教程:youtube.com/…

以上是关于java中import和class.forName的区别的主要内容,如果未能解决你的问题,请参考以下文章

java反射中,Class.forName和classloader的区别(代码说话)

Java中new和Class.forName的区别

在 Java 的反射中,Class.forName 和 ClassLoader 的区别

java反射中,Class.forName 和 ClassLoader 加载类的区别

在java反射中 Class.forName和classLoader的区别

java中Class对象详解和类名.class, class.forName(), getClass()区别