若是是用Exlipse, 第三方的包能够放在eclipse文件夹的jre包的lib文件夹中!
(初学者的一些总结~高手们勿喷哈~)html
缘由:java
之前一直用Eclispe编程环境运行Java。很是舒服,就像用傻瓜相机照相通常。linux
有看见许多高手都是直接用vim编辑文件,命令行编译运行,以为那样不是反而更繁琐?编程
转折点是在前几天本科毕设题目选定以后。毕设题是一个基于java 字节码的类关系动态分析。须要对.class文件中字节码进行更改(具体的说是在许多指令后加入作标记的新指令,以实现动态跟踪的目的)。vim
我发现,eclipse根本没法如此灵活,他没法直接装载运行一个我修改过的.class文件。它是照顾大多数的通常状况。它为咱们作了不少事情:自动将.java源文件编译成.class字节文件,帮咱们加载类、运行。但却没法知足我个性化的需求。命令行虽然麻烦,倒是更加本质。windows
至少从这一点上看,java的命令行编译运行仍是很是重要的。oracle
我查阅了很多网上资料,发现资料虽多,却并不齐全,也不是太清晰。因而整理以下,但愿对初涉java命令行编译运行的筒子有些帮助吧!eclipse
许多初学者编译运行时候的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 PATH and CLASSPATH 和 Setting the class path。
jar包
java里用package的概念避免重复命名的问题。有点像C++的namespace。同一个包里的类是能够直接使用的。不一样包的话,则须要在.java文件头部import进对应的package。初学者写的helloworld程序固然是不用注意到包的问题,但当工程愈来愈大,重复命名的可能性增大,咱们就必须依靠package的概念来更好的管理咱们的代码了。
同时,为了方便管理、传输,jar包出现了。
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的缩写
-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.java file... Sample.java $ cat x/Sample.java # ...which looks like this. package x; public class Sample { public static void main(String... 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加载类时的查找目录。(关于类的加载,能够参照另几篇文章 classloader 三原则 和java 类加载器浅析 )
雷区:
在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时,就出现这个错误 = =。
若是还有问题,你们能够多交流啊~