Java - PATH, JAVA_HOME, CLASSPATH 简介

  1. 概述

    1. Java 环境变量简介
    2. 不讲配置
  2. 背景

    1. 想在 win10 上弄 多个版本 的 JDK
    2. 回想起大学, 刚学 Java 每次都要整 环境变量
      1. 又要加这个, 又要加哪个的, 看着就烦
      2. 其实就最多不超过 5 个而已...
      3. 算了不说了, 越说越丢人
    3. 工作以后, 基本也都是 ide 帮忙
      1. 自己没去想, 觉得理所当然, 觉得没必要
    4. 好像 Java SE 8 之后, windows 上安装 Java, 就会自己把这些配做好
      1. 所以我更没兴趣看了
      2. 现在想想, 还是看看吧
  3. 类型

    1. 教程类
      1. 简单的介绍
      2. 没有单独的结论
  4. 环境

    1. win10

      1. 20H2
    2. java

      1. Java SE 8

1. 环境变量

  1. 概述

    1. 各种环境变量
  2. 环境变量

    1. PATH
    2. JAVA_HOME - 非必要
    3. CLASSPATH - 非必要

1. PATH

  1. 概述

    1. PATH
  2. PATH

    1. 概述

      1. 环境变量
      2. 告诉操作系统, 可执行程序的位置
    2. 内容

      1. win10
        1. 一系列路径
        2. 用 ; 隔开
        3. 可以引用其他 ENV, 用 %% 表示引用
      2. linux
    3. 使用

      1. 使用者

        1. 操作系统
          1. 对我们来说, 通常是 命令行
      2. 过程: 命令行

        1. 用户: 输入命令
        2. 操作系统: 在 PATH 里搜索命令
          1. 找到, 就执行
          2. 没找到, 就不执行
    4. 疑问

      1. 问题1: 我没有 path, 会怎么样

        1. 问题

          1. 没有设定 path, 程序就不能跑了吗?
        2. 解答

          1. 没有设定 path, 程序可以跑
          2. 但是, 执行的时候, 需要做特殊处理
            1. 方案1: 进入到程序所在的目录
            2. 方案2: 执行命令时, 带上命令的 相对/绝对路径
      2. 问题2: 这个东西, 会冲突吗?

        1. 问题

          1. path 会冲突吗
            1. java 1.5 和 java 1.6 都在 path 里
            2. 这种情况, 怎么处理
          2. 如果冲突了怎么办
          3. 有没有优先级
        2. 解答

          1. 这个冲突, 我不知道怎么解释
          2. path 搜索机制
            1. 从左到有
            2. 如果找到, 就不会往下继续了
          3. 所以说, 之前的那个场景
            1. java 1.5 和 java 1.6 谁在前面, 就执行谁
          4. 用户变量 如果和 系统变量 冲突
            1. 会优先执行 用户变量
              1. 如果优先执行系统变量, 那用户差异不就体现不出来了?
  3. Java 的 Path

    1. 概述

      1. Java 的 Path
    2. Java 的 Path

      1. 概述

        1. 就是 Java 可执行文件的位置
      2. 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
        
  4. 配置过程

      1. 这个到处都讲烂了, 我也不废话了
  5. 验证

    1. 概述

      1. 验证配置
    2. 步骤

      1. 用户: 打开 cmd
      2. cmd: 输入命令 java -version
        1. 如果返回结果, 说明配置成功了
    3. 我的结果

      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

  1. 概述

    1. JAVA_HOME
  2. JAVA_HOME

    1. 概述

      1. 环境变量
      2. 通常都是设置的 java 安装路径
    2. 配置

      1. 环境变量名
        1. JAVA_HOME
        1. Java 的安装路径

          C:\Program Files\Java\jdk1.8.0_181
          
    3. 使用

      1. 组合

        # 配置 PATH
        ## 原来的值: C:\Program Files\Java\jdk1.8.0_181\bin
        %JAVA_HOME%\bin
        
  3. 疑问

    1. 问题: 为什么
      1. 问题

        1. 为什么要搞这个东西
        2. 直接写到 PATH 里, 又不是不能用
      2. 解答

        1. 如果我有多个 JDK, 我可以定义这么两个变量
          1. JAVA_08_HOME
          2. JAVA_11_HOME
          3. 最后用 JAVA_HOME 来引用其中一个
          4. tomcat 依赖这个东西, 所以我被迫做了妥协
        2. 切换的时候, 应该会方便一些吧...

3. CLASSPATH

  1. 概述

    1. CLASSPATH
  2. CLASSPATH

    1. 概述

      1. 环境变量
      2. java 程序运行时, 寻找类库的路径
    2. 类加载

      1. 时机

        1. jvm 启动时
      2. 工作

        1. 加载各种类库
      3. CLASSPATH

        1. 告诉 jvm, 需要在这里找类库
    3. 内容

      1. jar/zip 包

        1. 概述
          1. 预先打好的 jar/zip 包
      2. 编译后的 class 目录

        1. 概述
          1. 用户 工程编译后, 产生的 class 目录
        2. 场景
          1. 包名
            1. org.example.App
          2. 编译好的 class 文件位置
            1. E:\JavaProjects\MavenDemoQuickStart\target\classes\org\example\App.class
        3. classpath
          1. E:\JavaProjects\MavenDemoQuickStart\target\classes\
        4. 前提
          1. 需要在这个目录, 按包结构, 把 Class 文件放好
        5. 思路
          1. JVM 就会按照 包名, 自己去把类的 class 文件找到
    4. 默认值

      1. .
        1. jvm 认为, 你所在的 工作目录, 就是 放好工程类文件的 classpath...
  3. 疑问

    1. 问题1: 只有个默认的不够用

      1. 问题

        1. 我自己有很多类, 比如 maven 引入的依赖
        2. 那些东西, 我怎么处理?
      2. 解决

        1. java 提供了多种配置 classpath 的方式
          1. 默认
          2. 环境变量 CLASSPATH
          3. 命令行参数 -cp | -classpath
    2. 问题2: 配置方法多了, 优先级怎么办

      1. 问题

        1. 这么多配置方法
        2. 用混了怎么办
        3. 有没有优先级?
      2. 解决

        1. 确是会有
          1. 环境变量 CLASSPATH 会覆盖默认
          2. -cp 会覆盖 CLASSPATH 和 默认
        2. 覆盖
          1. 被覆盖的, 完全就不生效了
          2. 所以, 配置的时候, 一定要在环境变量里, 加上 "." 这个值
    3. 问题3: 这些配置方法, 我选哪个

      1. 问题

        1. 二选一, 选哪个?
      2. 解答

        1. 选择: 命令行参数 -cp
          1. CLASSPATH

            1. 优势
              1. 简单
            2. 劣势
              1. 当多个 jvm 需要在系统上执行的时候, 无法做到兼顾
              2. 优先级低
          2. -cp

            1. 可以弥补 环境变量 的劣势
    4. 问题3: 同名组件的加载, 会有优先级吗

      1. 问题

        1. 同一个包, 能否加载多次
        2. 如果不能, 那怎么整?
      2. 解答

        1. 首先, 这个答案, 我不太确定
        2. 一般情况下, 同一个包, 只能加载一次
          1. 就算在 classpath 里重复了, 也只会加载第一次出现的那个
          2. 这也导致了一些时候, 出现 类库冲突 的问题
        3. 当然, 你也可以尝试, 通过对 类加载器 做一些处理, 来加载这些东西
    5. 问题4: jvm 自己的类库, 是怎么搞得?

      1. 问题

        1. jvm 自己也有类库, 一般是怎么加载的
      2. 解答

        1. 通常情况下, jvm 会用 类加载器, 来加载类
        2. 但是 jvm 有三个类加载器
          1. bootstrap

            1. 概述
              1. 加载 java 本身的类库
              2. 这个 classpath, 是不需要指定的
                1. sun.boot.class.path 里固定了, 而且是 只读
                2. 实在要制定, 可以用 -Xbootclasspath
            2. 位置
              1. %JAVA_HOME%/jre/lib
            3. 内容
              1. rt.jar
              2. 其他
          2. extension

            1. 概述
              1. 加载一些 拓展类
              2. 这个 classpath, 也是不需要指定的
            2. 位置
              1. %JAVA_HOME%/jre/ext
          3. user

            1. 概述
              1. 加载第三方类
            2. 位置
              1. classpath 指定
    6. 问题5: 使用 ide 的时候, 是什么情况

      1. 问题

        1. ide 是怎么处理的
      2. 解答

        1. 我在最后附加了一个 ide 的 java 启动命令
          1. 最后还是 ide 一人扛下了所有

ps

  1. ref

    1. PATH

      1. 这个网站, 我没上去了
      2. 能上的就看看吧
    2. The PATH Variable in Windows - Explained.

      1. 这也是个一会儿能上, 一会儿不能上的网站
    3. Windows7环境变量中,系统变量与用户变量的优先级

      1. windows 的系统逻辑, 应该不会随便就改了吧
    4. Managing the Java classpath

      1. 06 年的老文章
        1. 讲的挺多挺全面的
        2. 我没看完
    5. PATH and CLASSPATH

      1. oracle 官方教程
        1. jdk8
    6. What's the default classpath when not specifying classpath?

      1. 解释得挺好的
    7. How Classes are Found

      1. jvm 如何找 class
        1. classpath 的优先级, 是从这里来的
    8. 2 Setting the Class Path

      1. 配置 classpath
    9. Java中重名类冲突处理机制和Jar包加载顺序

      1. classloader 对 重名包 的处理
  2. 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
    
  3. 后续

    1. 问题1: 打包

      1. 我用 maven 默认配置打了个 jar 包
      2. 发现里面只有我自己代码的 class
      3. 没有其他的 class
      4. 所以, 如果这个包要到其他地方执行, 是不是得想点其他什么办法, 来解决依赖的问题?
    2. 问题2: 加载同一个类的多个版本

      1. ref
        1. Java Classloader - Handling Multiple Versions of The Same Class
posted @ 2021-01-02 21:50  轩辕拾銉  阅读(229)  评论(0编辑  收藏  举报