首页新闻找找看学习计划

Java中import导入类与加载类有什么区别

0
[已解决问题] 解决于 2017-08-24 14:54
  • 以 Jdbc为例 :Class.forName("com.mysql.jdbc.Driver"),这句话为什么不能替换成在首部导入驱动类:import com.mysql.jdbc.Driver ?? 
  • --------好吧,第二次修改------
  • import A;导入类A是否在运行时会将类A导入内存
岂止是一丝涟漪的主页 岂止是一丝涟漪 | 菜鸟二级 | 园豆:216
提问于:2017-07-21 12:42
< >
分享
最佳答案
0

import是给编译器用的,

class.forName是运行时生效的,

奖励园豆:5
苍枫露雨 | 小虾三级 |园豆:1027 | 2017-07-22 13:48

谢答!
我知道的是 Class.forName(A)这个方法会将类A加载到内存当中,而类A一旦被加载到内存中时,就会执行类A中的静态代码块。所以我想的是,利用import A;应该也能将类A加载到内存中,从而实现同样的效果。可是貌似编译时,会删除无用的导入类,即使我加入了@SuppressWarnings("unused")也会删除。。。。。。

岂止是一丝涟漪 | 园豆:216 (菜鸟二级) | 2017-07-22 15:02

@爱前端的后端Coder: 

不行的,即使不删除也没用,import只在编译的时候用,给你举个例子:

有两个类A,B, 在B中import了A, 

B:

import org.test.A

.....

public static void main(String[] args){

  A a = new A();

}

 

那么B在编译之后变成了:

public static void main(String[] args){

  org.test.A a = new org.test.A();

}

 

这就是import的作用,编译之后再无作用

与类加载没有任何关系

 

苍枫露雨 | 园豆:1027 (小虾三级) | 2017-07-24 12:07
其他回答(4)
-2

你这个有点鸡蛋里挑骨头的样子    照着写不就好了嘛!

长跑 | 园豆:11 (初学一级) | 2017-07-21 17:25
0

这个问题问的很尖锐

鸿燕藏锋 | 园豆:568 (小虾三级) | 2017-07-21 21:17
0

很好的问题,为此我特地实验了一下,直接import Driver, 然后DriverManager.registerDriver(Driver());是可行的的,事实上,看com.mysql.jdbc.Driver源码发现其内部就是执行了如下静态代码块:

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

为啥jdk作者或者是mysql驱动开发者不直接让开发人员new,而是通过类全称来加载Driver类,我能想到的一点原因是 根据字符串来加载类可以做到java代码与具体数据库解耦分离,通常我们会将驱动类的全称写进配置文件,需要切换数据库时,只需修改配置文件即可,而java代码几乎可以不用做任何修改;而使用new加载创建Driver实例就不行了。

学数学的程序猿 | 园豆:252 (菜鸟二级) | 2017-07-22 00:30

再补充一点,直接import com.mysql.jdbc.Driver;不写DriverManager.registerDriver(new Driver());也是可行的!缺点还是如上。

支持(0) 反对(0) 学数学的程序猿 | 园豆:252 (菜鸟二级) | 2017-07-22 00:34

@学数学的程序猿: 谢答!直接import com.mysql.jdbc.Driver;这样是不行的,我反编译后,发现因为导入的这个Driver类,因为并没用用到,所以,编译器编译时会直接删除这句导包的语句:import com.mysql.jdbc.Driver;
我知道的是 Class.forName(A)这个方法会将类A加载到内存当中,而类A一旦被加载到内存中时,就会执行类A中的静态代码块。所以我想的是,利用import A;应该也能将类A加载到内存中,从而实现同样的效果。可是貌似编译时,会删除无用的导入类,即使我加入了@SuppressWarnings("unused")也会删除。。。。。。  

支持(0) 反对(0) 岂止是一丝涟漪 | 园豆:216 (菜鸟二级) | 2017-07-22 15:01

@爱前端的后端Coder: 我昨晚试的是可以的。之前也想到编译器可能会做优化,删除"无用"的语句,但事实上它没有,我用的是java8,不知你用的是啥版本?

支持(0) 反对(0) 学数学的程序猿 | 园豆:252 (菜鸟二级) | 2017-07-22 15:04

@学数学的程序猿: 我用的也是java8、myeclipse、真的是反复清理、刷新了好几次,确认编译后的文件的确删除了那条导入语句。。。。。

支持(0) 反对(0) 岂止是一丝涟漪 | 园豆:216 (菜鸟二级) | 2017-07-22 15:08

@爱前端的后端Coder: 确实被删除了,但我发现啥都不写直接DriverManager.getConnection(...)居然也成功获取到数据了,有图为证:

支持(0) 反对(0) 学数学的程序猿 | 园豆:252 (菜鸟二级) | 2017-07-22 15:27

@学数学的程序猿: 应该报的是 找不到驱动的错误,不清楚你的什么情况  -_-

支持(0) 反对(0) 岂止是一丝涟漪 | 园豆:216 (菜鸟二级) | 2017-07-22 15:30
-2

这是一个很简单的语法知识,Class.forName#String 是执行Class类的静态方法,你这里的“com.mysql.jdbc.driver”是参数而已,在java文件中,使用类需要写类全名(如直接写com.mysql.jdbc.Driver),或者写简名Driver,前提是在在前面写import 包名,Class类属于java.lang包,默认包含java.lang

TCG2008 | 园豆:1145 (小虾三级) | 2017-07-22 10:07

谢答!
我知道的是 Class.forName(A)这个方法会将类A加载到内存当中,而类A一旦被加载到内存中时,就会执行类A中的静态代码块。所以我想的是,利用import A;应该也能将类A加载到内存中,从而实现同样的效果。可是貌似编译时,会删除无用的导入类,即使我加入了@SuppressWarnings("unused")也会删除。。。。。。

支持(0) 反对(0) 岂止是一丝涟漪 | 园豆:216 (菜鸟二级) | 2017-07-22 15:02

@爱前端的后端Coder: 

我觉得已经说得够清楚了,import只是语法,最终看生成class文件,如果你了解更多的话应该去看class文件结构.Class#forName 查看官方文档http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#forName-java.lang.String-

支持(0) 反对(0) TCG2008 | 园豆:1145 (小虾三级) | 2017-07-22 21:57
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册