编译 java_自己动手编译、运行Java程序

本人初学Java,看到别人都说学Java先不要用Eclipse、NetBeans这些开发工具,所以索性就自己试试。过程犯的错误极多,参照着李刚老师那本疯狂Java一点一点的实验.由于自己使用过Makefile,所以就用Makefile做了实验,总算是可以不用Eclipse、NetBeans就能自己编译运行一些小的程序了,下面就是我自己总结的心得,如有错误,请大家指正,谢谢。

本文分四小节:

第一节:配置Java运行时环境

第二节:代码的编译以及运行

第三节:如何打jar包以及使用jar包

第四节:利用Makefile自动编译运行Java程序

第一节:配置Java运行时环境

本节以Windows XP为例,来配置Java运行环境。这节很简单,我就长话短说。

1:下载JDK开发包,解压安装。

2:在用户环境变量中增加PATH变量(在系统的环境变量中增加也行,但是可能需要重新启动操作系统),并设置其值。

例如我把JDK安装在F:\program\java目录下,则把PATH变量设置成F:\program\java\jdk\bin,因为这个路径下有我们要编译、运行Java程序所需要的所有工具,比如javac.exe,java.exe,jar.exe....。之后我们就可以在cmd下使用javac、java、jar等命令了。

例如有一下Java源文件Test.java,执行javac Test.java就会在当前目录下生成Test.class文件。之后我们运行java Test即可运行程序。当然也可以人为指定class文件的生成位置,利用-d选项。比如 javac -d D:\ Test.java,那么就可以在D:\目录下看到Test.class了。

第二节:代码的编译以及运行

对于写Java程序而言,我们主张源文件与class文件都有相同的目录结构,这样不仅会方便代码的组织管理,也使得在编译以及运行Java程序时少犯错误。

1:位于默认包下的文件的编译以及运行

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngView Code

//D:\src\A.java

classA{private intvalue;publicA(){

value= 0;

}public void setValue(intvar){

value=var;

}public intgetValue(){returnvalue;

}

}//D:\src\Test.java

public classTest{public void static voidmain(String[] args){

A a= newA();

a.setValue(10);

System.out.println(a.getValue());

}

}

我们运行javac Test.java,会发现D:\src目录下多了A.class和Test.class两个文件。运行java Test则可以在Dos中看到输出为10。我们发现这两个Java文件中并没有package语句,所以这两个文件同属于一个默认包中(没有显示写package的文件都是属于默认包的)。

2: Java类发现规则

要想成功编译java文件,需要有classpath和包名的共同配合。

类发现规则:class文件所在目录 = classpath + '\' + 包名中的'.'全变成'\'

这个规则大家一定要记住,保证万事OK!Java就是靠这个规则来寻找需要的class文件的。

例如:classpath=D:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngView Code

//D:\src\A.java

packagesrc;public classA{private intvalue;publicA(){

value= 0;

}public void setValue(intvar){

value=var;

}public intgetValue(){returnvalue;

}

}//D:\Test.java

import src.*;public classTest{public void static voidmain(String[] args){

A a= newA();

a.setValue(10);

System.out.println(a.getValue());

}

}

如果想要javac Test.java成功,则需要在D:\src(D:\src = D:\ + src)路径下能够找到A.class,否则编译出错。如果不存在D:\src目录,则会返回包名不存在的错误信息。如果D:\src存在,但是该路径下不存在A.class时,则报告没有找到class文件。如果java文件存放目录正确,并且也正确的指定了其所在的包,则javac会自动编译A.java来生成A.class。

例如:上例就能够正确的生成所有需要的class文件。但是如果把A.java中package语句去掉。之后编译A.java生成A.class文件,之后在D:\下运行javac Test.java并不会成功,虽然在D:\src下存在A.class文件。

所以综上所述,package语句中包名必须与生成的class文件所在的目录保持一个关系,使得javac能够找到相应的class文件并且验证一个文件是否处于正确的包中。

那么classpath是什么呢?从名字也能猜得到,classpath代表class文件的存放路径。这是个环境变量,可以添加到用户的环境变量中,其值则根据编程时具体包名、以及类的存放路径来设定。如果不想用环境变量,也可在编译时用-classpath来设置。

classpath可以设置多个路径,路径之间利用';'相隔。编译时,javac会逐个尝试classpath的每个路径和文件的包名的组合,直到找到相应的class文件为止。但是如果通过classpath与包名的组合在多个不同的路径下都找到了同名类,则会返回错误信息。

由于javac默认情况下在java文件的当前目录生成class文件,所以人们经常把'.'添加到classpath中,代表当前文件所在的路径。高版本的Java编译以及运行程序可能会自动把'.'添加到classpath中。上面的例子中由于Test.java位于A.java的上一级目录中,所以把classpath设置成'.'时,也能编译成功。

现在说说把classpath设置成'.',它代表当前运行目录。那么什么是这个当前运行目录呢?其实就是运行javac时所在的目录,注意:切不可认为是当前编译的那个java文件所在的目录。

如果java文件中显示的写了package packagename 则为class文件指定了包,那么这个class文件也必须应在packagename转换后的相应子目录下。如果不写,则表示该class文件在默认包中。

现在来说说如运行java程序。

例如:classpath=D:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngView Code

/D:\src\A.javapackagesrc;public classA{private intvalue;publicA(){

value= 0;

}public void setValue(intvar){

value=var;

}public intgetValue(){returnvalue;

}

}//D:\src\Test.java

packagesrc;import src.*;public classTest{public void static voidmain(String[] args){

A a= newA();

a.setValue(10);

System.out.println(a.getValue());

}

}

我们如何运行这个程序呢?

首先在src目录下运行: javac Test.java

之后在任意目录下运行:java  src.Test

注意:切不可运行java Test命令,会提示找不到类的错误(即使在Test.class文件所在目录也不行)。所以运行指定了package程序时,需要显示的写出其包名,即:java packagename.classname,其遵循与class文件一样的寻找规则,即在classpath+packagename中'.'变成'\' 所表示的路径下能够找到相应的classname所指的class文件。

第三节:如何打jar包以及使用jar包

打jar包使用jar命令。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngView Code

//D:\src\A.java

packagesrc;public classA{private intvalue;publicA(){

value= 0;

}public void setValue(intvar){

value=var;

}public intgetValue(){returnvalue;

}

}

首先在src目录下运行javac A.java生成A.class。之后在D:\目录下运行jar -cvf test.jar src就会在D:\这个目录下生成test.jar,即我们打的jar包。那么我们如何使用这个jar包呢?首先必须把test.jar的路径加入到classpath中。之后我们有如下的测试程序。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngView Code

import src.*; //必须得有此import,因为A.class位于src包中。如果不写则编译不通过。

public classB{public static voidmain(String[] args){

A a= newA();

}

}

jar文件其实是一个压缩包,可以很容易的用解压软件进行解压。解压后有如下目录关系:

test.jar

|--src---|--A.java

|--A.class

这里可以把test.jar当成目录来处理,javac会自动在classpath中解压这个test.jar并根据B.java中的import找到其中的src文件夹下的A.class文件并使用。

现在看看我们的打包命令 jar -cvf test.jar src  //意思是把src文件夹整个打包

如果我们这么打包: 在src目录下运行jar -cvf test.jar A.java A.class,行吗?答案是不行。因为这样打包后路径关系为:

test.jar

|--A.java

|--A.class

javac寻找A.class时发现test.jar下不存在src目录,则会报不存在包的错误。所以大家一定要注意打包时应该把那个目录打进去,不应把哪个目录打进去。如果对属于默认包的class文件打包,则只要把jar包路径添加到classpath中即可使用,无需再在程序中使用import。当然jar命令还有很多参数可选,来满足各种不同需要的打包需求,这些就不说了。

4:利用Makefile自动编译运行Java程序

下面给出一个简单的例子:这个例子中,没有手动设置Windows的环境变量,而是用-classpath指定,这样方便在不同机器之间移植。

如下目录结构:

project---|---src---|---main---|---Test.java

| |---package1---|---A.java

| | |---B.java

| |

| |---package2---|---C.java

| |---Makefile

|

|---classes---|---main---|---Test.class

|---package1---|---A.class

| |---B.class

|

|---package2---|---C.class

代码如下:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngView Code

//A.java

packagepackage1;public classA{private intvalue;public A(){ value = 0; }public void setValue(intvar){

value=var;

}public intgetValue(){returnvalue;

}

}//B.java

packagepackage1;public classB{privateString name;public B(){ name = null; }public voidsetName(String name){this.name =name;

}publicString getName(){returnname;

}

}//C.java

packagepackage2;public classC{privateString name;public C(){ name = null; }public voidsetName(String name){this.name =name;

}publicString getName(){returnname;

}

}//Test.java

import java.util.*;import package1.*;import package2.*;public classTest{public static voidmain(String[] args){

A a= newA();

B b= newB();

C c= newC();

a.setValue(3);

b.setName("Java");

c.setName("Test");

System.out.println(a.getValue());

System.out.println(b.getName());

System.out.println(c.getName());

}

}

Makefile如下:

//Makefile

target:

javac ./package1/A.java -d ../classes

javac ./package1/B.java -d ../classes

javac ./package2/C.java -d ../classes

javac ./main/Test.java -d ../classes/main/ -classpath ../classes

run:

java -classpath ../classes/main;../classes Test

clean:

rm -rf ../classes/package1/*.class

rm -rf ../classes/package2/*.class

rm -rf ../classes/main/*.class

运行:make

D:\Java\project\src>make

javac ./package1/A.java -d ../classes

javac ./package1/B.java -d ../classes

javac ./package2/C.java -d ../classes

javac ./main/Test.java -d ../classes/main/ -classpath ../classes

运行:make run

D:\Java\project\src>make run

java -classpath ../classes/main;../classes Test

3

Java

Test

这样,其实我们完全可以不用Eclipse、Netbeans等开发工具就能自己编译运行自己的系统了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值