昨晚在写《第三篇 打造JAVA开发环境——EditPlus篇》时候,配置CodeGenerator插件后,发现在命令行中执行java命令时总提示找不到类(当然,我确定路径没有问题),这个问题之前在公司电脑上也遇到了(也是在配置了CodeGenerator插件后),那时候以为是JDK出现了问题,但又不想重新安装。这个问题竟然在我的电脑上再次出现,这说明不是JDK出问题了。那么问题出现在哪里呢?
记得刚开始学习JAVA的时候,很多书、视频上或者老师都会讲解java环境变量的设置。安装好Java后,通常需要配置几个环境变量:JAVA_HOME、PATH、CLASSPATH。当时也就是按照他们讲的做,至于原因或他们的作用却不是很了解,我想大部分人初学的时候都是这种状况,因为讲解的人一般都没有讲解所以然。今天遇到了环境变量相关的问题,于是将这些问题总结一下。
1 Java安装时要注意的问题
安装Java时,会建议不要把JDK安装在带有空格的路径中,如Program Files。为什么要这样建议呢?书上或老师的说法是:这样其他需要使用Java的软件有可能出现莫名其妙的问题。至于为什么会出现“莫名其妙的问题”却不得而知。其实,这个问题还是很好理解的。在命令行中,命令和选项、参数等是通过空格分割的,如果javac/java命令(因为其他软件引用该命名时,一般会使用完整路径)路径中有空格,空格前面部分会被当作命令来处理,显然会出问题。实际上,类文件路径中,如果包含空格,编译或运行时,这个路径是需要放在引号中的,否则会被当作两部分来处理。
2 Java环境变量配置是要注意的问题
其实安装完Java后,不配置环境变量也是可以用的。只是在命令行中使用Java相关命令需要带上完整路径而已。然而这样很不方便,还有就是Eclipse之类由Java编写的软件会运行不了。所以配置必要的环境变量还是很有必要的。
2.1 JAVA_HOME环境变量
配置过程就不说了,主要讲述一下该变量的作用。其实,就Java本身来说,是不需要JAVA_HOME环境变量的。该环境变量只是用于其它软件(由Java编写的)找到Java的安装路径,例如Ant就需要先配置JAVA_HOME环境变量。
2.2 PATH环境变量
配置该变量是为了方便使用Java相关命令时,不需要输入完整的路径,只需要输入命令名即可。
2.3 CLASSPATH环境变量
不少教程甚至老师都说要配置该环境变量,把rt.jar 和 tools.jar等加入其中。其实根本不需要,这些类是由JAVA启动类装载器(Boostrap Classloader)装载的,这些是启动类(Boot
strap classes)。
在这讲解一下JAVA程序运行时如何查找类文件?(以下来自51cto“http://developer.51cto.com/art/200907/135263.htm”)
根据JDK文档说明, JAVA程序以以下3种顺序查找运行的类文件。
◆Bootstrap classes (*)
◆Extension classes
◆Users classes
2.3.1 Bootstrap classes
就是JAVA在启动时载入的类文件,这些类文件主要是rt.jar和jre/lib 目录下的一些类文件。Bootstrap过程中的class path是保存在 sun.boot.class.path系统属性中的。可以通过System.out.println(System.getProperty("sun.boot.class.path")); 来显示。同时Bootstrap classes 可以通过 -Xbootclasspath 命令行参数来指定。
下面列出了系统中默认的Bootstrap classes:
jre\lib\rt.jar; jre\lib\i18n.jar;
jre\lib\sunrsasign.jar; jre\lib\jsse.jar;
jre\lib\jce.jar; jre\lib\charsets.jar;
jre\classes
* Bootstrap
bootstrap是皮鞋后部的一条小带子或一个小环,它可以使你方便地把鞋子穿起来。在计算机中,是指使用一个很小的程序将某个特定的程序(通常是指操作系统)载入计算机中。
2.3.2 Extension classes (扩展类文件)
Extension classes主要是指的jre/lib/ext目录下的类文件,这些文件必须在jar文件或 zip文件中。如果不同名字的jar文件包含有相同的类文件,那么哪一个类文件被载入是不确定的。
2.3.3 User classes (用户自定义的类文件)
现在到了最重要的地方了,我们常说的CLASSPATH设置其实就是指定 User classes。JAVA按照以下四种顺序查找User classes。
2.3.3.1 默认的User classes . (dot) 就是指当前目录。
2.3.3.2 系统变量CLASSPATH设置所指定的类库,该变量覆盖(override)默认的User classes。
2.3.3.3 用命令行参数 -cp 或 -classpath指定的类库。这个时候覆盖默认的User classes 和CLASSPATH设置变量。
2.3.3.4 通过-jar 参数指定的jar文件。此时覆盖上面的三种情况,如果使用这种情况,所有的类文件必须来自指定的jar 文件。
了解了java如何查找User classes,我们接下来将要学习如何设置CLASSPATH变量。
2.3.4 配置CLASSPATH环境变量
如果只是一般运用java,只是用到java的基本库文件,练练手而已,则不需要CLASSPATH设置。
但是在一般开发情况下,这是很少遇到的。所以我们要自己CLASSPATH设置 。
我们一般的方法就是按照2.3.3.2 来设置CLASSPATH系统变量,像开始设置path一样,我们可以添加一个CLASSPATH设置的系统变量。网上有些文章所提到的添加rt.jar 和 tools.jar 等等是不需要的,因为这些类库是属于Bootstrap classes的。我们只要定义User classes ,如果我们要编译servlet 那么只要servlet-api.jar 和 jsp-api.jar 就可以实现基本的需要了。
另外要注意的是2.3.3.2 override 2.3.3.1。我们CLASSPATH设置时要将 .(dot)[表示当前目录]放在CLASSPATH设置中,然后用 ;(semicolon)分隔开来。由于其他提供的类文件都是放在jar文件中,我们设置时一定要将完整的jar 文件包含在CLASSPATH 设置中,而不是将其目录添加到CLASSPATH 设置中(很重要的一点)。
这个时候又一个问题出现了,当需要添加的jar 文件过多时,管理java 类库变得很麻烦。所以我认为在基础学习时用命令行编译调试,有利于JAVA的学习,但是到开发时则一般会要用到 IDE 工具(现在比较流行的是eclipse 和 netbeans ),或者通过Ant来编译。
3 总结
到这里,文章开始的问题便明朗了:没有配置CLASSPATH时,没有错误,配置了反而出错了,这就是因为2.3.3.2覆盖2.3.3.1。所以,在配置CLASSPATH时,应该将“.;”放在最前面,以便首先在当前目录搜索。
JAVA环境变量配置的相关问题就讲到这里,希望对您有所帮助。关于类装载器是一个很重要的问题,以后会专门写“JAVA虚拟机学习”的序列文章,其中就会详细讲解类装载器,敬请期待。