Java - PATH, JAVA_HOME, CLASSPATH 简介
-
概述
- Java 环境变量简介
- 不讲配置
-
背景
- 想在 win10 上弄 多个版本 的 JDK
- 回想起大学, 刚学 Java 每次都要整 环境变量
- 又要加这个, 又要加哪个的, 看着就烦
- 其实就最多不超过 5 个而已...
- 算了不说了, 越说越丢人
- 工作以后, 基本也都是 ide 帮忙
- 自己没去想, 觉得理所当然, 觉得没必要
- 好像 Java SE 8 之后, windows 上安装 Java, 就会自己把这些配做好
- 所以我更没兴趣看了
- 现在想想, 还是看看吧
-
类型
- 教程类
- 简单的介绍
- 没有单独的结论
- 教程类
-
环境
-
win10
- 20H2
-
java
- Java SE 8
-
1. 环境变量
-
概述
- 各种环境变量
-
环境变量
- PATH
- JAVA_HOME - 非必要
- CLASSPATH - 非必要
1. PATH
-
概述
- PATH
-
PATH
-
概述
- 环境变量
- 告诉操作系统, 可执行程序的位置
-
内容
- win10
- 一系列路径
- 用 ; 隔开
- 可以引用其他 ENV, 用 %
% 表示引用
- linux
- 略
- win10
-
使用
-
使用者
- 操作系统
- 对我们来说, 通常是 命令行
- 操作系统
-
过程: 命令行
- 用户: 输入命令
- 操作系统: 在 PATH 里搜索命令
- 找到, 就执行
- 没找到, 就不执行
-
-
疑问
-
问题1: 我没有 path, 会怎么样
-
问题
- 没有设定 path, 程序就不能跑了吗?
-
解答
- 没有设定 path, 程序可以跑
- 但是, 执行的时候, 需要做特殊处理
- 方案1: 进入到程序所在的目录
- 方案2: 执行命令时, 带上命令的 相对/绝对路径
-
-
问题2: 这个东西, 会冲突吗?
-
问题
- path 会冲突吗
- java 1.5 和 java 1.6 都在 path 里
- 这种情况, 怎么处理
- 如果冲突了怎么办
- 有没有优先级
- path 会冲突吗
-
解答
- 这个冲突, 我不知道怎么解释
- path 搜索机制
- 从左到有
- 如果找到, 就不会往下继续了
- 所以说, 之前的那个场景
- java 1.5 和 java 1.6 谁在前面, 就执行谁
- 用户变量 如果和 系统变量 冲突
- 会优先执行 用户变量
- 如果优先执行系统变量, 那用户差异不就体现不出来了?
- 会优先执行 用户变量
-
-
-
-
Java 的 Path
-
概述
- Java 的 Path
-
Java 的 Path
-
概述
- 就是 Java 可执行文件的位置
-
win10
# 假设, 我的 Java SE 8 装在下面的位置 ## C:\Program Files\Java\jdk1.8.0_181 ## path 就是安装路径下的 bin 目录 ## 进去看看, java, javac 一系列东西都在里面 C:\Program Files\Java\jdk1.8.0_181\bin
-
-
-
配置过程
- 略
- 这个到处都讲烂了, 我也不废话了
- 略
-
验证
-
概述
- 验证配置
-
步骤
- 用户: 打开 cmd
- cmd: 输入命令
java -version
- 如果返回结果, 说明配置成功了
-
我的结果
java version "1.8.0_201" Java(TM) SE Runtime Environment (build 1.8.0_201-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)
-
2. JAVA_HOME
-
概述
- JAVA_HOME
-
JAVA_HOME
-
概述
- 环境变量
- 通常都是设置的 java 安装路径
-
配置
- 环境变量名
- JAVA_HOME
- 值
-
Java 的安装路径
C:\Program Files\Java\jdk1.8.0_181
-
- 环境变量名
-
使用
-
组合
# 配置 PATH ## 原来的值: C:\Program Files\Java\jdk1.8.0_181\bin %JAVA_HOME%\bin
-
-
-
疑问
- 问题: 为什么
-
问题
- 为什么要搞这个东西
- 直接写到 PATH 里, 又不是不能用
-
解答
- 如果我有多个 JDK, 我可以定义这么两个变量
- JAVA_08_HOME
- JAVA_11_HOME
- 最后用 JAVA_HOME 来引用其中一个
- tomcat 依赖这个东西, 所以我被迫做了妥协
- 切换的时候, 应该会方便一些吧...
- 如果我有多个 JDK, 我可以定义这么两个变量
-
- 问题: 为什么
3. CLASSPATH
-
概述
- CLASSPATH
-
CLASSPATH
-
概述
- 环境变量
- java 程序运行时, 寻找类库的路径
-
类加载
-
时机
- jvm 启动时
-
工作
- 加载各种类库
-
CLASSPATH
- 告诉 jvm, 需要在这里找类库
-
-
内容
-
jar/zip 包
- 概述
- 预先打好的 jar/zip 包
- 概述
-
编译后的 class 目录
- 概述
- 用户 工程编译后, 产生的 class 目录
- 场景
- 包名
org.example.App
- 编译好的 class 文件位置
E:\JavaProjects\MavenDemoQuickStart\target\classes\org\example\App.class
- 包名
- classpath
E:\JavaProjects\MavenDemoQuickStart\target\classes\
- 前提
- 需要在这个目录, 按包结构, 把 Class 文件放好
- 思路
- JVM 就会按照 包名, 自己去把类的 class 文件找到
- 概述
-
-
默认值
.
- jvm 认为, 你所在的 工作目录, 就是 放好工程类文件的 classpath...
-
-
疑问
-
问题1: 只有个默认的不够用
-
问题
- 我自己有很多类, 比如 maven 引入的依赖
- 那些东西, 我怎么处理?
-
解决
- java 提供了多种配置 classpath 的方式
- 默认
- 环境变量 CLASSPATH
- 命令行参数 -cp | -classpath
- java 提供了多种配置 classpath 的方式
-
-
问题2: 配置方法多了, 优先级怎么办
-
问题
- 这么多配置方法
- 用混了怎么办
- 有没有优先级?
-
解决
- 确是会有
- 环境变量 CLASSPATH 会覆盖默认
- -cp 会覆盖 CLASSPATH 和 默认
- 覆盖
- 被覆盖的, 完全就不生效了
- 所以, 配置的时候, 一定要在环境变量里, 加上 "." 这个值
- 确是会有
-
-
问题3: 这些配置方法, 我选哪个
-
问题
- 二选一, 选哪个?
-
解答
- 选择: 命令行参数 -cp
-
CLASSPATH
- 优势
- 简单
- 劣势
- 当多个 jvm 需要在系统上执行的时候, 无法做到兼顾
- 优先级低
- 优势
-
-cp
- 可以弥补 环境变量 的劣势
-
- 选择: 命令行参数 -cp
-
-
问题3: 同名组件的加载, 会有优先级吗
-
问题
- 同一个包, 能否加载多次
- 如果不能, 那怎么整?
-
解答
- 首先, 这个答案, 我不太确定
- 一般情况下, 同一个包, 只能加载一次
- 就算在 classpath 里重复了, 也只会加载第一次出现的那个
- 这也导致了一些时候, 出现 类库冲突 的问题
- 当然, 你也可以尝试, 通过对 类加载器 做一些处理, 来加载这些东西
-
-
问题4: jvm 自己的类库, 是怎么搞得?
-
问题
- jvm 自己也有类库, 一般是怎么加载的
-
解答
- 通常情况下, jvm 会用 类加载器, 来加载类
- 但是 jvm 有三个类加载器
-
bootstrap
- 概述
- 加载 java 本身的类库
- 这个 classpath, 是不需要指定的
- sun.boot.class.path 里固定了, 而且是 只读
- 实在要制定, 可以用 -Xbootclasspath
- 位置
- %JAVA_HOME%/jre/lib
- 内容
- rt.jar
- 其他
- 概述
-
extension
- 概述
- 加载一些 拓展类
- 这个 classpath, 也是不需要指定的
- 位置
- %JAVA_HOME%/jre/ext
- 概述
-
user
- 概述
- 加载第三方类
- 位置
- classpath 指定
- 概述
-
-
-
问题5: 使用 ide 的时候, 是什么情况
-
问题
- ide 是怎么处理的
-
解答
- 我在最后附加了一个 ide 的 java 启动命令
- 最后还是 ide 一人扛下了所有
- 我在最后附加了一个 ide 的 java 启动命令
-
-
ps
-
ref
-
- 这个网站, 我没上去了
- 能上的就看看吧
-
The PATH Variable in Windows - Explained.
- 这也是个一会儿能上, 一会儿不能上的网站
-
- windows 的系统逻辑, 应该不会随便就改了吧
-
- 06 年的老文章
- 讲的挺多挺全面的
- 我没看完
- 06 年的老文章
-
- oracle 官方教程
- jdk8
- oracle 官方教程
-
What's the default classpath when not specifying classpath?
- 解释得挺好的
-
- jvm 如何找 class
- classpath 的优先级, 是从这里来的
- jvm 如何找 class
-
- 配置 classpath
-
- classloader 对 重名包 的处理
-
-
classpath
# 这是我的 IntelliJ Idea 里, 一个小程序的启动命令 ## 我整理了一下格式 ## 问题是, 这里的 classpath, 把 rt.jar 和 ext 的东西, 也加进来了, 我还不知道是为啥 "C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:E:\Program Files\JetBrains\IntelliJ IDEA 2020.3\lib\idea_rt.jar=8339:E:\Program Files\JetBrains\IntelliJ IDEA 2020.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar; C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar; E:\JavaProjects\MavenDemoQuickStart\target\classes; C:\Users\<user>\.m2\repository\org\apache\logging\log4j\log4j-core\2.13.0\log4j-core-2.13.0.jar; C:\Users\<user>\.m2\repository\org\apache\logging\log4j\log4j-api\2.13.0\log4j-api-2.13.0.jar" org.example.App
-
后续
-
问题1: 打包
- 我用 maven 默认配置打了个 jar 包
- 发现里面只有我自己代码的 class
- 没有其他的 class
- 所以, 如果这个包要到其他地方执行, 是不是得想点其他什么办法, 来解决依赖的问题?
-
问题2: 加载同一个类的多个版本
-
尽量尝试解释清楚; 自己校对能力有限, 如果有错误欢迎指出