javac命令编译项目,java命令执行项目

我们平时大量的使用IDE工具,可能连这个基本的命令怎么用的都不知道了,今天就来使用这个命令编译一个java项目。

1.编译java项目

首先有一个java项目

上面的这个项目是我用eclipse创建的一个普通项目,在eclipse中,其编译java项目之后会将生成的class文件放置在bin目录中,然后lib目录是我们自己创建的,使用javac编译项目的时候需要手动的指定jar包的位置

我们的项目源文件放置在src中,我们现在使用javac命令来手动编译这个项目,同样也可以指定输出class文件到bin目录下,只要是用javac的时候加上对应的参数就可以了。

我们首先来简单的试一试,看看行不行,之前使用javac的时候都是编译的一个文件,这次要编译一个工程,还真不知道该从何处下手。

javac命令在编译一个.java文件的时候,发现一个未知的类,其会该类的class文件,如果关联的class类不存在的话,就会去找对应的java文件进行编译,那是不是说,我们编译main函数所在的文件就可以编译所有的.java文件了?试试看。

下面分别是core包下和utils包下的java文件,我们来尝试编译,BootStrap是入口文件。

-encoding指定了文件的编码,编译器就会以该编码来读取我们的jar文件

-cp是指定CLASSPATH(如果不指定,默认就是当前运行javac命令所在文件夹),编译器在查找一个类关联的类的时候会根据CLASSPATH进行查找,比如说你在一个类文件中import了另外一个包的java文件,javac就会根据CLASSPATH去查找这个java文件。如果你一个编译的java文件在中关联了另外一个类,javac会先到看import是否导入了该类,如果不是导入的,也就说说他和当前类是同一个包下的,这种情况javac也能正常编译。javac会使用路径:CLASSPATH+当前编译的类的包路径去查找该类。比如你现在在编译com\web\A.java文件,然后A的类中关联了另外一个类B,类B与A是在同一包下,所以在A.java中不需要使用import关键字去进行导入,所以javac会使用CLASSPATH路径+A的包路径去查找类B然后进行编译。(如果没有设置CLASSPATH,默认情况下就是javac命令运行的路径)

注意-cp后面的写法,..\lib\*;.  使用“;”分割了两个路径,因为CLASSPATH可以不止一个,这里的..\lib\*是在我这用来加载所有的jar包的,“.”就是指当前路径,这样就能正确的编译了,能找到所有所依赖的.java文件和.class文件。

注意:在指定编译路径时,对于jar包必须要指定全路径即路径+文件名的格式,不能只指定一个路径,所以我们上面加载jar包的路径使用了“*”进行通配,而不能只指定文件夹。

但是编译出来.class文件和java文件在同一个路径下了,这时候就需要使用-d参数了,其用来设置类文件的输出目录

 

最终就能在bin目录下出现所有编译后的class文件  

 

我们在使用javac编译项目的时候,一般只需要指定main方法所在的类即可,而不需要像c语言那样每个.c文件都需要指定

例如现在有三个java文件在同一个包下.

T.java文件

public class T {

    public static void main(String[] args)  {
        A a = new A();
    }

}

A.java文件

public class A {
    B b;
}

B.java文件

public class B{

}

那么我们要编译该项目的命令如下

javac T.java

既我们只需要指定main方法所在的java文件即可,然后javac在编译的过程中会去寻找关联到的每一个java文件的每一个符号,这样最终我们整个项目的java文件都会被编译.

就比如上面:编译T.java时,内部有一个A,javac就会去找A进行编译,然后编译A时又发现需要B,又会去找B进行编译.

 

java命令执行项目

现在存在一个java工程,工程下存在一个package,也就是一个文件夹

有main函数的class在该文件下,那么我们执行该class的时候必须要在当前chaoxing所在文件夹下,因为main函数所在的类所属的package是chaoxing,如果直接到class文件所在路径去执行会出现找不到或无法加载主类

执行命令如下

java chaoxing.Main

编译和运行都是要去特别注意路径的问题,也就是package的问题和CLASSPATH的问题,大多数的问题都是因为路径出现了问题而导致找不到对应的java文件或者说找不到对应的class文件而导致出现问题,java命令找寻一个类使用的是CLASSPATH+package作为class的路径,javac找寻一个java文件是根据CLASSPATH+import来找寻一个.java文件或者是一个已经存在的.class文件

 

java命令行执行程序解决依赖外部jar包的问题

用java命令行直接执行程序,如果这个程序需要引用外部jar包。就不能单纯用java xx来执行

如果你的jar包和程序就在一个目录:

编译

javac -cp yy/yy.jar,xx/xx.jar test.java

执行

java -cp yy/yy.jar,xx/xx.jar test

注意:-cp会覆盖我们在系统上设置的环境变量

但是往往我们依赖的包很多,要一个个填写估计就疯了。所有我们一般会把所有的外部依赖包都放在一个文件夹里,比如在./lib

编译 

javac -Djava.ext.dirs=./lib test.java

执行

java  -Djava.ext.dirs=./lib test

-Djava.ext.dirs是设置的ExtClassLoader加载器的加载路径,且ExtClassLoader加载器只能加载jar包,不能加载.class文件

但是这并不是说AppClassLoader类加载器只能加载.class文件,其也能加载jar文件,我们上面一个一个指定jar包的方式,那么该jar包就会由AppClassLoader类加载器加载

注意:-Djava.ext.dirs=./lib 覆盖java本身设置的java.ext.dirs属性,java默认情况下该值为$JAVA_HOME/lib/ext。

java.ext.dirs指定的目录由ExtClassLoader加载器加载。我们覆盖了默认的属性之后就会导致我们会失去一些功能,例如java自带的加密算法。

所以,我们设置的时候需要带上原来的默认情况下的属性值,这样就不会出现问题了

-Djava.ext.dirs=.:$JAVA_HOME/jre/lib/ext

 

javac和java -cp参数的区别

javac -cp 指明了.java文件里import的类的位置,也就是编译时检查对应的类存不存在,不存在编译就不能通过。

java -cp 指明了去哪些文件夹下寻找运行时需要加载的class文件,既指定系统类加载器的类加载目录。假如我们现在执行java命令所在的文件夹不是我们要执行的class所在的文件夹,就需要通过该参数来指定对应的目录,这样才能执行成功。同时java后面指定要执行的class的时候,不能使用绝对路径,只能使用其所在包的名称。

假设我们现在有个Test.class文件在C:/user/11/desktop/com/c文件夹下,com.c既是他的报名

# 这种方式来执行该class是错的,因为java后面写要执行的class文件写的应该是其所在包的名称,而不是路径。
java C:/user/11/desktop/com/c/Test

# 应该像这样,但是这样要求我们的 C:/user/11/desktop路径在环境变量classpath中,这样java命令才能找到该类,否者是找不到的,因为java命令执行class文件就是根据 classpath+类的全限定名来确定类所在位置
java com.c.Test

# 如果不想把路径放到classpath中,因为我们有时候可能只是临时执行,就可以使用-cp参数来指定classpath,且其优先级比环境变量中的高
java -cp  C:/user/11/desktop com.c.Test
# 使用该参数之后,不管我们在哪个路径下执行该class文件,都会成功

一般我们在class包所在文件夹中执行class文件时不用使用-cp参数,这是大多数都在classpath中设置了 "."这个路径来指定当前路径就是其中一个类加载路径。

 

如果我们编译的一个工程中,有多个相同的类文件(全限定名相同),那么javac会去编译哪一个.java文件呢?

当然这种情况肯定要指定多个classpath,同一个classpath下操作系统不会允许有同名文件,就是在多个文件下有相同的.java文件的请情况下,javac命令会编译最先找到的那一个,因为javac命令本身就是按照顺序一个路径一个路径的找,所以其会编译最先找到的一个。如果是java命令也是一样的,其会加载最先找到的那个class.

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值