从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 新闻合订本
    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 新闻合订本
    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

    • 我的 Java 学习路线
    • 安装 Java
    • Java 数据类型

    • Java 多版本配置
    • 面向对象

      • 枚举类
      • static 关键字
      • classpath:JVM 查找类的机制
        • 编译一个类
        • 全局 classpath
        • 命令行里的 classpath
        • 多个 classpath
        • 如何编译多个类
        • javac 的参数
        • 参考
        • 编译一个类
        • 全局classpath
        • 命令行里的classpath
        • 多个classpath
        • 如何编译多个类
        • javac的参数
        • 小结
        • 参考
      • 包:Java 组织类的方式
      • jar 包
      • class 版本
      • 抽象类
      • 接口
      • 访问性修饰符
      • 非访问性修饰符
      • 内部类
    • Java 核心类

    • IO

    • Java 与时间

    • 异常处理

    • 哈希和加密算法

    • Java8 新特性

    • 网络编程

  • JavaSenior

  • JavaEE

  • JavaWeb

  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java
  • JavaSE
  • 面向对象
2022-11-26
目录

classpath:JVM 查找类的机制

# classpath:JVM 查找类的机制

对于刚跨入 Java 门槛的初学者来说,编译和运行一个简单的类或许很简单,但如果涉及到多个类、类存放的路径不一样、涉及到 jar 包的时候,就可能稍微复杂了。这里的难点在于对 classpath 的理解和设置上。本文通过理论与实践相结合的方式,逐步解决编译过程中各种 classpath 的方式,并有相关的练习和代码。通过本文,读者应该能在不借助 IDE 的情况下编译和运行代码。

本文环境:Windows10 + Java8。 其他环境也可以运行本博客讲解到的程序(毕竟 Java☕ 是跨平台的)

# 编译一个类

还记得我们的第一个 Java 程序吗?我们新建了一个目录,然后创建了 Hello.java 文件,编写代码:

public class Hello{
    public static void main(String[] args){
        System.out.println("Welcome to Java!");
    }
}
1
2
3
4
5

我们这里假设新目录为 D:\JavaTest

然后我们在文件所在目录,打开命令行,将 Java 源文件翻译成 Java 字节码文件并执行:

D:\JavaTest> javac Hello.java
D:\JavaTest> java Hello    
Welcome to Java!
1
2
3

我们目前是直接在存放源码的文件夹中进行编译和运行的,一些重要的问题没有暴露出来:

  1. 操作系统如何寻找 javac 和 java 命令? 答:由于 javac 和 java 命令是可执行文件,操作系统会根据我们安装 Java 的时候配置的 path 去寻找这两个文件;
  2. 操作系统如何寻找 Hello.java 和 Hello.class 文件?此时,就不是根据我们安装 Java 时的 path 变量去寻找了,到底如何查找呢?我们一步步测试并分析。

我们将命令行所在目录回退到上一级,此时,当前路径就不是源码存放的路径了,然后我们输入 javac 命令:

D:\> javac Hello.java
javac: 找不到文件: Hello.java
用法: javac <options> <source files>
-help 用于列出可能的选项
1
2
3
4

有报错找不到文件,这很正常,因为源码不在当前路径下。我们需要指定一个路径:

D:\> javac D:\JavaTest\Hello.java
1

这回不报错了,编译成功。

接下来我们尝试执行:

D:\> java D:\JavaTest\Hello
错误: 找不到或无法加载主类 D:\JavaTest\Hello
1
2

明明 Hello/Hello.class 是一个 class 文件,为什么就找不到了呢?

原来,Java 对待.java​文件与.class​文件是有区别的。对.java 文件可以直接指定路径给它,而 java 命令所需的.class 文件不能出现扩展名,也不能指定额外的路径给它。请牢记这一点。

那么,对于 Java 所需的 .class 文件,如何指定路径呢?必须通过 classpath 来指定。

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

# 全局 classpath

我们配置一个新的环境变量。首先打开环境变量窗口,然后在用户变量中新建一个变量,变量名为 classpath,变量值为 D:\JavaTest

重新打开一个新的 cmd,输入 java Hello

C:\WINDOWS\system32> java Hello
Welcome to Java!
1
2

可以看到,即使我们不在源码所在目录,也能运行 Java 程序;由此可见,classpath 环境变量的作用就是告诉 JDK 去哪里寻找 .class 文件。一旦设置了 classpath 变量,以后每次运行 java 或 javac 命令时,如果要查找.class 文件,都会去 classpath 里找。这是一个全局的设置。

如果有新程序就设置 classpath 变量,那么也太麻烦了,我们可以在运行 Java 程序的时候指定一个 classpath:

D:\> java -classpath D:/JavaTest Hello
Welcome to Java!
1
2

JDK 发现有 classpath 选项后,就会先根据此 classpath 指定的路径寻找 .class 文件,找不到再去全局的 classpath 环境变量中寻找。我们可以试着删除环境变量,打开一个新的 CMD,然后再次执行上述命令。

tips: 可以用 classpath 的缩写 cp 来代替,如下:

D:\> java -cp D:/JavaTest Hello
Welcome to Java!
1
2

1.特别注意的是,JDK 1.5 之前,javac 命令不能用 cp 来代替 classpath,而只能用 classpath

如果 .class 文件路径带有空格,需要加上双引号,例如

javac "D:\Java Test\Hello.java"
java -classpath "D:\Java Test" Hello
1
2

请自行尝试有空格的情况。

# 命令行里的 classpath

当我们编译的类里面,包含其他类的时候,该怎么编译呢?我们举个例子:

在 Hello.java 的同级目录下新建一个 Person.java

public class Person {
  private String name;
  public Person (String name){
    this.name = name;
  }

  public String getName() {
    return name;
  }
}
1
2
3
4
5
6
7
8
9
10

修改 Hello.java

public class Hello{
  public static void main(String[] args){
    Person person = new Person("Peter");
      System.out.println(person.getName());
  }
}

1
2
3
4
5
6
7

接下来,我们尝试编译

D:\> javac D:/JavaTest/Hello.java
D:\JavaTest\Hello.java:3: 错误: 找不到符号
    Person person = new Person("Peter");
    ^
  符号:   类 Person
  位置: 类 Hello
D:\JavaTest\Hello.java:3: 错误: 找不到符号
    Person person = new Person("Peter");
                        ^
  符号:   类 Person
  位置: 类 Hello
2 个错误
1
2
3
4
5
6
7
8
9
10
11
12

此时我们可以看到 JDK 报错找不到 Person 类。为什么之前可以通过指定源码的路径,来编译,现在不行呢?因为之前的 Hello 类中没有用到其他类,因此 JDK 不需要去寻找其他类;

而现在,我们用到了 Person 类,我们就得告诉 JDK,去哪里找这个类(即使他们在同一个文件夹下)

D:\> javac -cp D:/JavaTest D:/JavaTest/Hello.java
1

编译通过,可以看到生成了 Person.class 文件。

实际上由于 Hello.java 使用了 Person.java 类,JDK 先编译生成了 Person.class,然后再编译生成 Hello.class。因此,不管 Hello.java 这个主类使用了多少个其他类,只要编译这个类,JDK 就会自动编译其他类,很方便。

我们尝试运行:

D:\> java -cp D:/JavaTest Hello
Peter
1
2

运行成功

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

# 多个 classpath

接下来我们试试,源码在不同目录的情况。

我们在 Hello 文件夹下新建一个名为 lib 的文件夹,将 Person.java 移动到其下面,并删除 Person.class 文件。

我们尝试编译:

D:\> javac -cp D:/JavaTest/lib D:/JavaTest/Hello.java
1

编译通过,因为 Person 在 lib 文件夹里,我们只需修改 classpath 为 lib 文件夹的目录即可

我们尝试运行:

D:\> java -cp D:/JavaTest Hello
Exception in thread "main" java.lang.NoClassDefFoundError: Person
        at Hello.main(Hello.java:3)
Caused by: java.lang.ClassNotFoundException: Person
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 1 more
1
2
3
4
5
6
7
8
9

有报错,因为我们没有指定 Person 的路径,有报错也是正常的。我们尝试指定:

D:\> java -cp D:/JavaTest/lib Hello
错误: 找不到或无法加载主类 Hello
1
2

还是有报错。。。为什么呢?

由于 Java 需要在不同文件夹下寻找 class 文件,而 classpath 只告诉了 JDK 一个路径,有错误也是正常的。

在本文的一开始,我们在编译一个类的时候,为什么不用指定 classpath 也能运行呢?因为默认 JVM 会从当前路径寻找类,如果指定了 classpath,就不从当前路径寻找了。

此时我们需要设置多个 classpath,以分号 “;”隔开(注意路径与分号之间不能有空格,Linux 上用冒号:分割):

D:\> java -classpath "D:\JavaTest;D:\JavaTest\lib" Hello
Peter
1
2

运行成功,但也暴露出一个问题,如果我们需要用到许多分处于不同文件夹下的类,那这个 classpath 的设置岂不是很长!有没有办法,对于一个文件夹下的所有.class 文件,只指定这个文件夹的 classpath,然后让 JDK 自动搜索此文件夹下面所有相应的路径?有,使用 package,且听下回分解。

# 如何编译多个类

当一个包下面很多类的时候,逐个编译是很累的。

比如我们在 JavaTest 下新建多个类,每个类都有 main 方法:

public class Hello{
  public static void main(String[] args){
      System.out.println("Hello");
  }
}
1
2
3
4
5
public class Hello2{
  public static void main(String[] args){
      System.out.println("Hello2");
  }
}
1
2
3
4
5
public class Hello3{
  public static void main(String[] args){
      System.out.println("Hello3");
  }
}
1
2
3
4
5

我们尝试编译:

D:\JavaTest> javac Hello.java Hello2.java Hello3.java
1

如果类比较多,每个都要写,容易写错或者写漏。

我们可以用通配符表示编译当前目录所有 java 文件:

D:\JavaTest> javac *.java
1

也可以指定编译某个目录下的所有 Java 文件:

 D:\> javac ./JavaTest/*.java
1

那能不能编译子目录下的所有文件呢?比如

javac JavaTest/**/*.java
1

其中,第一个星号表明所有子文件夹,第二个星号表明所有 java 文件。也就是编译 JavaTest 目录下所有子文件夹的 java 代码。很遗憾,在 Windows 下是不行的,Windows 不支持这种通配符,得逐个写出各个类…………但是在 Linux 下是可以的,笔者试着在 Git Bash 里也可以用这种通配符,有兴趣的读者请自行尝试

不过一般我们会使用 IDE 开发,会自动根据包结构编译所有 Java 源码,无需使用这么复杂的命令;但我们最好还是了解这一点,知道 IDE 背后帮我们做了什么事情。

tomcat,kafka 这些大型项目的启动运行,都是在脚本里设置 classpath 的。

# javac 的参数

命令行 -d 指定输出的 class 文件存放到具体的目录。例如:

D:\> mkdir ./JavaTest/bin
D:\> javac -d ./JavaTest/bin ./JavaTest/*.java
1
2

然后可以看到在 bin 目录下存放了 class 文件

D:\JavaTest\bin\Hello.class
D:\JavaTest\bin\Hello2.class
D:\JavaTest\bin\Hello3.class
1
2
3

注意:请自己独立完成上述实验过程,如果有问题再好好看看该博客,以确保确实掌握了 classpath 的概念和使用。

# 参考

本文主要是参考廖雪峰老师的博客,自己动手实践而得,感谢:

包 - 廖雪峰的官方网站 (opens new window)

classpath 和 jar - 廖雪峰的官方网站 (opens new window)

Java 入门实例 classpath 及 package 详解 - 橘子山寨 - BlogJava (opens new window)

对于刚跨入Java门槛的初学者来说,编译和运行一个简单的类或许很简单,但如果涉及到多个类、类存放的路径不一样、涉及到jar包的时候,就可能稍微复杂了。这里的难点在于对classpath的理解和设置上。本文通过理论与实践相结合的方式,逐步解决编译过程中各种classpath的方式,并有相关的练习和代码。通过本文,读者应该能在不借助IDE的情况下编译和运行代码。

本文环境:Windows10 + Java8。 其他环境也可以运行本博客讲解到的程序(毕竟Java☕ 是跨平台的)

# 编译一个类

还记得我们的第一个Java程序吗?我们新建了一个目录,然后创建了Hello.java文件,编写代码:

public class Hello{
    public static void main(String[] args){
        System.out.println("Welcome to Java!");
    }
}
1
2
3
4
5

我们这里假设新目录为D:\JavaTest ‍ 然后我们在文件所在目录,打开命令行,将Java 源文件翻译成 Java字节码文件并执行:

D:\JavaTest> javac Hello.java
D:\JavaTest> java Hello      
Welcome to Java!
1
2
3

‍ 我们目前是直接在存放源码的文件夹中进行编译和运行的,一些重要的问题没有暴露出来:

  1. 操作系统如何寻找 javac 和 java命令? 答:由于javac 和 java命令是可执行文件,操作系统会根据我们安装Java的时候配置的path去寻找这两个文件;
  2. 操作系统如何寻找 Hello.java 和 Hello.class文件?此时,就不是根据我们安装Java时的path变量去寻找了,到底如何查找呢?我们一步步测试并分析。 ‍ 我们将命令行所在目录回退到上一级,此时,当前路径就不是源码存放的路径了,然后我们输入javac命令:
D:\> javac Hello.java
javac: 找不到文件: Hello.java
用法: javac <options> <source files>
-help 用于列出可能的选项
1
2
3
4

有报错找不到文件,这很正常,因为源码不在当前路径下。我们需要指定一个路径:

D:\> javac D:\JavaTest\Hello.java
1

这回不报错了,编译成功。

接下来我们尝试执行:

D:\> java D:\JavaTest\Hello
错误: 找不到或无法加载主类 D:\JavaTest\Hello
1
2

明明Hello/Hello.class 是一个class文件,为什么就找不到了呢?

原来,Java对待.java文件与.class文件是有区别的。对.java文件可以直接指定路径给它,而java命令所需的.class文件不能出现扩展名,也不能指定额外的路径给它。请牢记这一点。

那么,对于Java所需的 .class文件,如何指定路径呢?必须通过classpath来指定。

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

# 全局classpath

我们配置一个新的环境变量。首先打开环境变量窗口,然后在用户变量中新建一个变量,变量名为 classpath,变量值为 D:\JavaTest

重新打开一个新的cmd,输入java Hello

C:\WINDOWS\system32> java Hello
Welcome to Java!
1
2

可以看到,即使我们不在源码所在目录,也能运行Java程序;由此可见,classpath环境变量的作用就是告诉JDK去哪里寻找 .class文件。一旦设置了classpath变量,以后每次运行java或javac命令时,如果要查找.class文件,都会去classpath里找。这是一个全局的设置。 ‍ 如果有新程序就设置classpath变量,那么也太麻烦了,我们可以在运行Java程序的时候指定一个classpath:

D:\> java -classpath D:/JavaTest Hello
Welcome to Java!
1
2

JDK发现有classpath选项后,就会先根据此classpath指定的路径寻找 .class文件,找不到再去全局的classpath环境变量中寻找。我们可以试着删除环境变量,打开一个新的CMD,然后再次执行上述命令。 ‍

tips: 可以用classpath的缩写cp来代替,如下:

D:\> java -cp D:/JavaTest Hello
Welcome to Java!
1
2

1.特别注意的是,JDK 1.5之前,javac命令不能用cp来代替classpath,而只能用classpath

如果.class文件路径带有空格,需要加上双引号,例如

javac "D:\Java Test\Hello.java"
java -classpath "D:\Java Test" Hello
1
2

请自行尝试有空格的情况。

# 命令行里的classpath

当我们编译的类里面,包含其他类的时候,该怎么编译呢?我们举个例子:

在Hello.java的同级目录下新建一个Person.java

public class Person {
  private String name;
  public Person (String name){
    this.name = name;
  }

  public String getName() {
    return name;
  }
}
1
2
3
4
5
6
7
8
9
10

修改Hello.java

public class Hello{
  public static void main(String[] args){
    Person person = new Person("Peter");
      System.out.println(person.getName());
  }
}

1
2
3
4
5
6
7

‍ 接下来,我们尝试编译

D:\> javac D:/JavaTest/Hello.java
D:\JavaTest\Hello.java:3: 错误: 找不到符号
    Person person = new Person("Peter");
    ^
  符号:   类 Person
  位置: 类 Hello
D:\JavaTest\Hello.java:3: 错误: 找不到符号
    Person person = new Person("Peter");
                        ^
  符号:   类 Person
  位置: 类 Hello
2 个错误
1
2
3
4
5
6
7
8
9
10
11
12

此时我们可以看到JDK报错找不到Person类。为什么之前可以通过指定源码的路径,来编译,现在不行呢?因为之前的Hello类中没有用到其他类,因此JDK不需要去寻找其他类;

而现在,我们用到了Person类,我们就得告诉JDK,去哪里找这个类(即使他们在同一个文件夹下)

D:\> javac -cp D:/JavaTest D:/JavaTest/Hello.java
1

编译通过,可以看到生成了Person.class文件。

实际上由于Hello.java使用了Person.java类,JDK先编译生成了Person.class,然后再编译生成Hello.class。因此,不管Hello.java这个主类使用了多少个其他类,只要编译这个类,JDK就会自动编译其他类,很方便。

我们尝试运行:

D:\> java -cp D:/JavaTest Hello
Peter
1
2

运行成功 ‍

# 多个classpath

接下来我们试试,源码在不同目录的情况。

我们在Hello文件夹下新建一个名为lib的文件夹,将Person.java 移动到其下面,并删除Person.class文件。

我们尝试编译:

D:\> javac -cp D:/JavaTest/lib D:/JavaTest/Hello.java
1

编译通过,因为Person在lib文件夹里,我们只需修改classpath为lib文件夹的目录即可 ‍ 我们尝试运行:

D:\> java -cp D:/JavaTest Hello
Exception in thread "main" java.lang.NoClassDefFoundError: Person
        at Hello.main(Hello.java:3)
Caused by: java.lang.ClassNotFoundException: Person
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 1 more
1
2
3
4
5
6
7
8
9

有报错,因为我们没有指定Person的路径,有报错也是正常的。我们尝试指定:

D:\> java -cp D:/JavaTest/lib Hello
错误: 找不到或无法加载主类 Hello
1
2

还是有报错。。。为什么呢?

由于Java需要在不同文件夹下寻找class文件,而classpath只告诉了JDK一个路径,有错误也是正常的。

在本文的一开始,我们在编译一个类的时候,为什么不用指定classpath也能运行呢?因为默认JVM会从当前路径寻找类,如果指定了classpath,就不从当前路径寻找了。

此时我们需要设置多个classpath,以分号 “;”隔开(注意路径与分号之间不能有空格,Linux上用冒号:分割):

D:\> java -classpath "D:\JavaTest;D:\JavaTest\lib" Hello
Peter
1
2

运行成功,但也暴露出一个问题,如果我们需要用到许多分处于不同文件夹下的类,那这个classpath的设置岂不是很长!有没有办法,对于一个文件夹下的所有.class文件,只指定这个文件夹的classpath,然后让JDK自动搜索此文件夹下面所有相应的路径?有,使用package,且听下回分解。 ‍

# 如何编译多个类

当一个包下面很多类的时候,逐个编译是很累的。

比如我们在JavaTest下新建多个类,每个类都有main方法:

public class Hello{
  public static void main(String[] args){
      System.out.println("Hello");
  }
}
1
2
3
4
5
public class Hello2{
  public static void main(String[] args){
      System.out.println("Hello2");
  }
}
1
2
3
4
5
public class Hello3{
  public static void main(String[] args){
      System.out.println("Hello3");
  }
}
1
2
3
4
5

‍ 我们尝试编译:

D:\JavaTest> javac Hello.java Hello2.java Hello3.java
1

如果类比较多,每个都要写,容易写错或者写漏。 ‍ 我们可以用通配符表示编译当前目录所有java文件:

D:\JavaTest> javac *.java
1

‍ 也可以指定编译某个目录下的所有Java文件:

 D:\> javac ./JavaTest/*.java
1

‍ 那能不能编译子目录下的所有文件呢?比如

javac JavaTest/**/*.java
1

其中,第一个星号表明所有子文件夹,第二个星号表明所有java文件。也就是编译JavaTest目录下所有子文件夹的java代码。很遗憾,在Windows下是不行的,Windows不支持这种通配符,得逐个写出各个类…………但是在Linux下是可以的,笔者试着在Git Bash里也可以用这种通配符,有兴趣的读者请自行尝试

不过一般我们会使用IDE开发,会自动根据包结构编译所有Java源码,无需使用这么复杂的命令;但我们最好还是了解这一点,知道IDE背后帮我们做了什么事情。

‍tomcat,kafka这些大型项目的启动运行,都是在脚本里设置classpath的。

# javac的参数

命令行-d指定输出的class文件存放到具体的目录。例如:

D:\> mkdir ./JavaTest/bin
D:\> javac -d ./JavaTest/bin ./JavaTest/*.java
1
2

‍ 然后可以看到在bin目录下存放了class文件

D:\JavaTest\bin\Hello.class
D:\JavaTest\bin\Hello2.class
D:\JavaTest\bin\Hello3.class
1
2
3

‍

# 小结

本文所有代码比较简单,也已放到Git上,并补充了相关说明:

Gitee:classpath · 小林/LearnJava - 码云 - 开源中国 (opens new window)

GitHub:classpath at master · Peter-JXL/LearnJava (opens new window) ‍ 注意:请自己独立完成上述实验过程,如果有问题再好好看看该博客,以确保确实掌握了classpath的概念和使用。

# 参考

本文主要是参考廖雪峰老师的博客,自己动手实践而得,感谢:

包 - 廖雪峰的官方网站 (opens new window)

classpath和jar - 廖雪峰的官方网站 (opens new window)

Java入门实例classpath及package详解 - 橘子山寨 - BlogJava (opens new window)

上次更新: 2025/6/3 09:31:54
static 关键字
包:Java 组织类的方式

← static 关键字 包:Java 组织类的方式→

最近更新
01
新闻合订本 2025-10
10-31
02
2025 年 10 月记
10-30
03
用 AI 批量优化思源笔记排版
10-15
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式