Java命令⾏编译项⽬
如果是⽤Exlipse,第三⽅的包可以放在eclipse⽂件夹的jre包的lib⽂件夹中!
(初学者的⼀些总结~⾼⼿们勿喷哈~)
原因:
以前⼀直⽤Eclispe编程环境运⾏。⾮常舒服,就像⽤傻⽠相机照相⼀般。
有看见许多⾼⼿都是直接⽤vim编辑⽂件,命令⾏编译运⾏,觉得那样不是反⽽更繁琐?
转折点是在前⼏天本科毕设题⽬选定之后。毕设题是⼀个基于java 字节码的类关系动态分析。需要对.class⽂件中字节码进⾏更改(具体的说是在许多指令后加⼊做标记的新指令,以实现动态跟踪的⽬的)。
我发现,eclipse根本⽆法如此灵活,他⽆法直接装载运⾏⼀个我修改过的.class⽂件。它是照顾⼤多数的⼀般情况。它为我们做了很多事情:⾃动将.java源⽂件编译成.class字节⽂件,帮我们加载类、运⾏。但却⽆法满⾜我个性化的需求。命令⾏虽然⿇烦,却是更加本质。
⾄少从这⼀点上看,java的命令⾏编译运⾏还是⾮常重要的。
我查阅了不少⽹上资料,发现资料虽多,却并不齐全,也不是太清晰。于是整理如下,希望对初涉java命令⾏编译运⾏的筒⼦有些帮助吧!
许多初学者编译运⾏时候的Exception的发⽣,下⾯的⽅法都能解决了~如果你遇到什么问题,仔细看看下⾯先~说不定有所帮助噢。
java的运⾏机制的基本概念:
源⽂件 也就是我们熟知的.java⽂件。
类⽂件  .class⽂件是编译器由.java⽂件编译⽽成。众所周知,Java的跨平台性在于Java虚拟机(JVM)这⼀层对硬件的隔离,⽽.class⽂件可以理解为JVM中的执⾏⽂件(⾃⼰的理解,可能不太准确)。⾥⾯存储的是java字节码,java bytecode 是基于栈的(stack based)(关于字节码和JVM更详细的官⽅解释可以参照 The Java Virtual Machine Specification ,如果嫌那本书太厚,另外再推荐⼀
本 Programming for the Java Virtual Machine)。
编译 Java的编译⼀般是指从源⽂件(.java⽂件)到类⽂件(.class⽂件)的转化过程。在JDK命令⾏中是 javac 命令(java compiler的缩写~跟C语⾔⽊关系的~)
运⾏ 在JVM中执⾏.class⽂件。是 java 命令。
CLASSPATH 环境变量,存储着编译某⽂件或运⾏某类时,所要搜索的⽬录。 ⽐如:在Hello.java中有使⽤到⼀个第三⽅包ThirdPart.jar 中的类,那么必须在classpath中添加相应的路径,让编译器能到它。(注意~把ThirdParty.jar放在当前的⼯作⽬录下,没有告诉环境变量也是不⾏的~编译器只认环境变量的!)同样的道理,在运⾏某类⽂件时,有涉及到第三⽅jar包的也必须添加到CLASSPATH中。⼀般的,有三种⽅式修改环境变量。
1.在javac 或者java命令中,使⽤ -classpath 选项,后⾯跟着需要的⽬录地址。显然,这种⽅法只能在当前语句范围内⽣效。
2.直接命令⾏修改CLASSPATH或者PATH  # PATH=$JAVA_HOME/bin:/home/username/bin
#export PATH
不过这种⽅法只能在此次运⾏中⽣效。
3.永久⽣效的⽅法是修改配置⽂件。在 /etc/profile 或者 /etc/profile.d 或者其他,不同操作系统发⾏版地点不同。在⽂件中加上CLASSPATH=......(相应路径),重启电脑即可(也可⼀执⾏source命令,那样不⽤重启就已经⽣效啦~# source /etc/profile.d    其实 . 跟source是⼀样的效果噢~ #. /etc/profile.d  )
PATH环境变量 跟CLASSPATH 类似,只不过它不是⽤来寻类的,⽽是⽤来寻java相关执⾏⽂件的。
可以通过 java -version 命令来查看⾃⼰是否已经设置好了PATH(如果显⽰了详细java信息,则已经设置好了,没有的话,还需要到java的安装位置,重新设置)
环境变量的具体相关信息,参照doc  和 。
jar包
java⾥⽤package的概念避免重复命名的问题。有点像C++的namespace。同⼀个包⾥的类是可以直接使⽤的。不同包的话,则需要在.java⽂件头部import进对应的package。初学者写的helloworld程序当然是不⽤注意到包的问题,但当⼯程越来越⼤,重复命名的可能性增⼤,我们就必须依靠package的概念来更好的管理我们的代码了。
同时,为了⽅便管理、传输,出现了。
jar包其实是⽤zip压缩的⽂件包。我们可以打包⾃⼰的package,⽅便复⽤,到哪果然,也可以直接引⽤⽂件夹(此时注意,必须引⽤⽂件夹的根⽬录,⽐如⽂件定义为package mypackage.foo , 那个必须将myapackage这个⽂件夹连同内部的foo⽂件⼀起放在相应的路径上)
制作jar压缩包和解压缩包的命令如下:
jar -cvf foo.jar foo
其中最后⼀个参数为需要压缩的⽂件包。-cvf⼏个选项中,f必须放在最后,f后⾯紧跟的必须是output的⽂件名。v表⽰输出详细信息(verbose)
对应的解压缩命令为:
jar -xvf foo.jar
注意其中有个可选的mainifest⽂件,在META-INF/MANIFEST.MF路径上。
我们可以在manifest.mf⽂件中加⼊如下语句
Main-Class: myPackage.MyClass
指定MyClass类为具有main()⼊⼝的主类。再利⽤如下语句,就可以值执⾏对应的程序了
java -jar foo.jar
命令
javac命令:编译源⽂件
-
classpath  初学者必须掌握的options ,后接类中使⽤到的第三⽅类(形式可以是jar或者zip或者直接就是⽂件包)的⽬录。linux下,多个⽬录⽤冒号 : 分隔。
值得注意的是,-classpath中的内容是会覆盖掉环境变量classpath中的内容的~
-cp 是 -classpath的缩写
java设置环境变量的方法代码-d  制定⽣成的.class⽂件存放的⽬录。
-o 此选项告诉javac优化由内联的static、final以及privite成员函数所产⽣的码。
-verbose 此选项告知Java显⽰出有关被编译的源⽂件和任何被调⽤类库的信息。⽐如 -verbose:class 能看到各种类加载的信息。 -verbose:gc是garbage collection的信息。
还有许多option平时⽤的不多(话说我也其实只是刚会⽤,并不熟练直接在命令⾏环境下的调试编译 = =),需要⽤的时候直接翻阅 man javac 好了。
java 命令:加载运⾏类⽂件
-classpath 跟javac中的-classpath同样的道理。
-
cp 也就是 -classpath的缩写啦。
-jar 执⾏在jar包上定义的主类的程序
⼀个.java⽂件的编译、运⾏⽰例如下:
# javac -classpath ./:/home/username/bin/ThirdParty.jar  Hello.java
#java -classpath ./:/home/username/bin/ThirdParty.jar  Hello
另外,对于带有package信息的java⽂件,执⾏如下:
$ ls .                  # Current directory contains the "x" package
x
$ ls x                  # The "x" package contains a Sample.
Sample.java
$ cat x/Sample.java      # ...which looks like this.
package x;
public class Sample {
public static void args) {
System.out.println("Hello from Sample class");
}
}
$ javac x/Sample.java    # Use "/" as delimiter and
# include the ".java"-suffix when compiling.
$ java x.Sample          # Use "." as delimiter when running, and don't include
# the ".class" suffix.
Hello from Sample class
补充:eclipse的路径
eclipse下,每个project都可以控制路径。
1.在package explorer⽬录下,右击⾃⼰的project。下拉菜单中点击最底部的properties,弹出的窗⼝的左侧,有Java Build Path这⼀选项卡。
这⾥主要是对其他⼯程包、第三⽅jar包的路径引⼊,也有对project中源⽂件路径的设置。
2.在run的下拉菜单中(就是那个绿⾊的Run开始按钮),选择Run Configuration.
在每个运⾏的程序中,都有main、argument、JRE、classpath、source、environment、common这⼏个选项卡。
其中argument⾥可以设置java命令⾏运⾏时的参数。也就试main(String[] args)中的args。
classpath⾥可以设置system classloader加载类时的查⽬录。(关于类的加载,可以参照另⼏篇⽂章 和 )
雷区:
在linux下运⾏时,添加⽬录,千万不要弄错分割符。windows下是 \ ,⽽linux下是 / 。
运⾏类时,不⽤加.class。⽐如有⼀个类Hello.class,运⾏命令是 # java  Hello ⽽不是 #java Hello.class 。运⾏机制中是寻类,⽽不是像编译的时候那样到某个⽂件。
如果引⽤的类有package层次,引⽤的路径是包层次的起点,⽽不可以延伸到包中的某个⽬录层次。⽐如引⽤了~/workspace⽬录下的第三⽅类 com.thirdparty.hello ,在java命令的 -classpath 输⼊的是第三⽅类的包的根⽬录所在位置: #java -classpath
~/workspaceHello,⽽不能是java -classpath ~/workspace/com/thirdparty  Hello。
NoSuchMethodException!
在运⾏⾃⼰的程序时,遇到了这个问题。查了很多资料,最后发现原来是路径问题!原来的路径中,⼀个⽼版本的.class⽂件是在优先的位置上,于是每次invoke⼀个新写的method时,就出现这个错误 = =。
如果还有问题,⼤家可以多交流啊~

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。