目录

classpath

jar包

小结


classpath

在Java中,我们经常听到classpath这个东西。网上有很多关于“如何设置classpath”的文章,但大部分设置都不靠谱。

到底什么是classpath

classpath是JVM用到的一个环境变量,它用来指示JVM如何搜索class

因为Java是编译型语言,源码文件是.java,而编译后的.class文件才是真正可以被JVM执行的字节码。因此,JVM需要知道,如果要加载一个abc.xyz.Hello的类,应该去哪搜索对应的Hello.class文件。

所以,classpath就是一组目录的集合,它设置的搜索路径与操作系统相关。例如,在Windows系统上,用;分隔,带空格的目录用""括起来,可能长这样:

C:\work\project1\bin;C:\shared;"D:\My Documents\project1\bin"

在Linux系统上,用:分隔,可能长这样:

/usr/shared:/usr/local/bin:/home/liaoxuefeng/bin

现在我们假设classpath.;C:\work\project1\bin;C:\shared,当JVM在加载abc.xyz.Hello这个类时,会依次查找:

  • <当前目录>\abc\xyz\Hello.class

  • C:\work\project1\bin\abc\xyz\Hello.class

  • C:\shared\abc\xyz\Hello.class

注意到.代表当前目录。如果JVM在某个路径下找到了对应的class文件,就不再往后继续搜索。如果所有路径下都没有找到,就报错。

classpath的设定方法有两种:

在系统环境变量中设置classpath环境变量,不推荐;

在启动JVM时设置classpath变量,推荐。

我们强烈不推荐在系统环境变量中设置classpath,那样会污染整个系统环境。在启动JVM时设置classpath才是推荐的做法。实际上就是给java命令传入-classpath-cp参数:

java -classpath .;C:\work\project1\bin;C:\shared abc.xyz.Hello

或者使用-cp的简写:

java -cp .;C:\work\project1\bin;C:\shared abc.xyz.Hello

没有设置系统环境变量,也没有传入-cp参数,那么JVM默认的classpath.,即当前目录:

java abc.xyz.Hello

上述命令告诉JVM只在当前目录搜索Hello.class

在IDE中运行Java程序,IDE自动传入的-cp参数是当前工程的bin目录和引入的jar包。

通常,我们在自己编写的class中,会引用Java核心库的class,例如,StringArrayList等。这些class应该上哪去找?

有很多“如何设置classpath”的文章会告诉你把JVM自带的rt.jar放入classpath,但事实上,根本不需要告诉JVM如何去Java核心库查找class,JVM怎么可能笨到连自己的核心库在哪都不知道?

不要把任何Java核心库添加到classpath中!JVM根本不依赖classpath加载核心库!

更好的做法是,不要设置classpath!默认的当前目录.对于绝大多数情况都够用了。

jar包

如果有很多.class文件,散落在各层目录中,肯定不便于管理。如果能把目录打一个包,变成一个文件,就方便多了。

jar包就是用来干这个事的,它可以把package组织的目录层级,以及各个目录下的所有文件(包括.class文件和其他文件)都打成一个jar文件,这样一来,无论是备份,还是发给客户,就简单多了。

jar包实际上就是一个zip格式的压缩文件,而jar包相当于目录。如果我们要执行一个jar包的class,就可以把jar包放到classpath中:

java -cp ./hello.jar abc.xyz.Hello

这样JVM会自动在hello.jar文件里去搜索某个类。

那么问题来了:如何创建jar包?

因为jar包就是zip包,所以,直接在资源管理器中,找到正确的目录,点击右键,在弹出的快捷菜单中选择“发送到”,“压缩(zipped)文件夹”,就制作了一个zip文件。然后,把后缀从.zip改为.jar,一个jar包就创建成功。

假设编译输出的目录结构是这样:

package_sample
└─ bin├─ hong│  └─ Person.class│  ming│  └─ Person.class└─ mr└─ jun└─ Arrays.class

这里需要特别注意的是,jar包里的第一层目录,不能是bin,而应该是hongmingmr。如果在Windows的资源管理器中看,应该长这样:

如果长这样:

说明打包打得有问题,JVM仍然无法从jar包中查找正确的class,原因是hong.Person必须按hong/Person.class存放,而不是bin/hong/Person.class

jar包还可以包含一个特殊的/META-INF/MANIFEST.MF文件,MANIFEST.MF是纯文本,可以指定Main-Class和其它信息。JVM会自动读取这个MANIFEST.MF文件,如果存在Main-Class,我们就不必在命令行指定启动的类名,而是用更方便的命令:

java -jar hello.jar

jar包还可以包含其它jar包,这个时候,就需要在MANIFEST.MF文件里配置classpath了。

在大型项目中,不可能手动编写MANIFEST.MF文件,再手动创建zip包。Java社区提供了大量的开源构建工具,例如Maven,可以非常方便地创建jar包。

小结

JVM通过环境变量classpath决定搜索class的路径和顺序;

不推荐设置系统环境变量classpath,始终建议通过-cp命令传入;

jar包相当于目录,可以包含很多.class文件,方便下载和使用;

MANIFEST.MF文件可以提供jar包的信息,如Main-Class,这样可以直接运行jar包。

java classpath 和 jar 简介相关推荐

  1. JAVA classpath设置方式启动详解:java class名、java -jar

    java classpath设置方式启动详解:java className.java -jar 文章目录 java classpath设置方式启动详解:java className.java -jar ...

  2. java classpath import package 机制 @Java的ClassPath, Package和Jar

    java classpath import package 机制 從一個簡單的例子談談package與import機制 基本原則:為什麼需要將Java文件和類文件切實安置到其所歸屬之Package所對 ...

  3. JAVA classpath jar问题[zz]

    classpath问题可以说是所有初学者头疼的问题,偶也一样. 1) classpath的作用:   它的作用就事让java找到你所要执行,或你拥有的类. 2) classpath的设置:   设置c ...

  4. JAVA CLASSPATH 和PATH的区别 经典

    JAVA CLASSPATH 和PATH的区别 收藏 PATH: 用来指定 java 虚拟机(JVM) 所在在目录,也就是我们最常用的用来编译java源程序的javac.exe 和用来执行 *.cla ...

  5. “java程序打成jar包 如何处理第三方jar包”

    eclipse的export的 runnable jar file 导出的jar包的形式应该可以避免这个问题,直接想所依赖的jar里的class文件也一并打入jar包里了. 问题一: 现在有一j2se ...

  6. java 执行jar_windows下如何用java指令运行jar包?

    step1:用eclipse导出(也可以用jar命令)jar包,并指定Main-Class,比如Main-Class:com.skymobi.csj.CsjMainstep2:编写batstep2.1 ...

  7. java项目打jar包

    http://www.cnblogs.com/tianguook/archive/2012/03/14/2396335.html java项目打jar包分为2种情况: 一.java项目没有导入第三方j ...

  8. java classpath设置_Java CLASSPATH设置

    Java CLASSPATH设置 CLASSPATH: CLASSPATH是一个环境变量,Application ClassLoader使用它来定位和加载.class文件. CLASSPATH定义路径 ...

  9. java项目打jar包的两种情况

    java项目打jar包的两种情况 本文介绍一下java项目打jar包时的两种情况各怎么操作 方法/步骤 1.  1 一.java项目没有导入第三方jar包 这时候打包就比较简单: 1.  首先在Ecl ...

最新文章

  1. 2018中国移动机器人行业十大热词
  2. 武汉加油!总有那么一个声音让我们感动,总有那些英雄在为难时刻挺身而出,像英雄们致敬。陈老师《大国风范》演讲视频...
  3. python代码覆盖率测试_利用coverage工具进行Python代码覆盖率测试
  4. linux cpu频率设置,linux cpu 频率设置
  5. 工作119:axios请求封装
  6. 一个黑色全屏的计时器_我入手了一个1000多的智能手环,值吗?|Fitbit Charge 4测评...
  7. kafka 同步提交 异步_Kafka 位移提交那些事儿
  8. python 清空文件_python:文件的读取、创建、追加、删除、清空
  9. AI虚拟偶像正崛起,是否可以取代你的idol?
  10. 今天中午吃什么转盘html,吃到撑的几种简单午饭,让你再也不发愁吃什么了!...
  11. 实验吧-web-天下武功唯快不破
  12. 取消管理员取得所有权_取消管理员取得所有权|右键管理员取得所有权|win10获取管理员权限...
  13. 关于Adobe flash player 本地播放器
  14. 90952-27-5,Thiol-PEG4-alcohol含有羟基和巯基的交联剂
  15. 吉林银行2021年上半年经营成果丰硕
  16. MOOC清华《面向对象程序设计》第9章:听课感想
  17. E06 【买衣服】Maybe you need a bigger size
  18. 在 Adob​​e MAX 深入研究 UI/UX 设计
  19. android 两个经纬度计算方位角和距离(Java版本)
  20. 2022年王道数据结构考研复习指导习题代码(栈和队列)

热门文章

  1. 架构师之路 — 数据库设计 — 关系型数据库理论
  2. Linux Kernel TCP/IP Stack — L1 Layer — NIC Controller — NAPI
  3. 用 Flask 来写个轻博客 (12) — M(V)C_编写和继承 Jinja 模板
  4. Git 远程仓库分支管理
  5. #ifdef __cplusplus
  6. 12.5寸新i5商务本 联想X220i报10888元
  7. shape(15,)与(15,1)的区别
  8. python - 异常处理
  9. java反射field和method的顺序问题
  10. 【发现】彻底清除www.go2000.cc的清除方法