Skip to content

fish-java/javac-java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Java命令行编译规则

Java程序的编译、运行是一件很头疼的事情,相信ClassNotFoundException是每个Java程序员都遇到过的事情。所以这次好好整理一下,希望后来者再也不会遇到这个问题了。

如果有读者朋友之前是写nodejs或者python这类的动态语言的,可能会对Java的编译机制很费解。nodejs它是基于文件系统进行模块管理的,程序员可以通过相对或绝对路径的来指明程序的入口文件,或者通过路径来指明依赖关系,文件和文件之间是互相交叉的网状或者树状结构。

但是其实Java的模块管理是基于包的,而且包和包之间是平行的关系。

当我们使用javac编译文件的时候,它其实做了这些事:

  • 通过相对路径找到入口文件,尝试编译

    比如说如果我们执行javac ./test/Hello.java的时候,它会到./test目录下寻找Hello.java文件

  • 如果发现Hello.java依赖了一些其他的包的class文件。javac就会尝试在它的搜索路径(后面说)里搜索这些包,确认它们是否存在

    • 如果存在

      就继续对Hello.java进行编译

    • 如果不存在相关的包以及class文件

      javac就会尝试搜索是否存在相关的.java文件

      • 如果存在

        把它们编译成class文件

      • 如果不存在

        抛出异常了

当我们使用java运行class文件的时候,它其实是会在classpath中寻找相关的包和class文件,完全不使用相对路径。(当然,包本生就暗含的相对路径的信息)

那么,java它是怎么查找.class文件的呢?

Java中的class文件有三种:

  1. Bootstrap classes

也就是JDK自带的工具包里面的class文件。

  1. Extension classes

用户下载的第三方jar包里面的class文件

  1. 用户项目中自定义的class

第一种只要你安装JDK后没有瞎折腾,javacjava肯定能找到,这里就不多说了。

我们关键说后两种情况,第三方包和用户自定义的包按照下面的规则来查找

  • 默认是.文件夹,也就是javac或者java的启动目录
  • 然后java会查看shell的环境变量,看看CLASSPATH的值
  • 通过-cp或者-classpath指定

多说无益,大家可以按照下面的顺序来阅读我给出的例子

文章列表

如果没有特殊说明,命令行程序都是在README.md 文件所在的目录执行的。

小写的java都是指命令行程序

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages