《java JDK7学习笔记》之跨平台与路径设置

Platforms表示Solaris、Linux、Windows各种操作系统平台,在这些平台上架构了java Virtaul Machine,简称JVM,Java虚拟机。

Java虚拟机可以让java跨平台。

深入了解跨平台

对于计算机而言,只认识一种语言,也就是0、1序列组成的机器指令。当使用C、C++等高级语言撰写程序时,这些语言是比较贴近人类可阅读的文法,也就是比较接近英语文法的语言。这是为了方便人类阅读及撰写,计算机其实看不到C/C++等编程语言,为了将C/C++翻译为0、1序列组成的机器指令,必须有个翻译员。担任翻译员工作的就是编译程序(Compiler)。

问题在于每个平台认识的0、 1序列并不一样。某个指令在Windows上的为0101,在linux上却是1010,因此必须使用不同的编译程序为不同的平台编译出可执行的机器指令,在windows编译好的程序不能再linux等其他平台上执行。也就是说,你的应用程序无法达到“一次编译,到处执行”的跨平台目的。

java是个高级语言,想在计算机上执行java撰写的程序,也得通过编译程序的翻译。不过java编译时,不直接编译为依赖于某个平台的0、 1序列,而是编译为中介格式的位码(Byte Code)。

java原始码扩展名为.java,经过编译程序翻译为扩展名为.class的位码。如果想要执行位码文档,目标平台必须安装JVM。JVM会将位码翻译为相依于平台的机器码。不同的平台必须安装专属该平台的JVM,JVM的职责就是将位码文档翻译为当前平台看得懂得0、 1序列。有了JVM,java程序就可以达到“一次编译,到处执行”的跨平台目的。

对java程序而言,只认识一种操作系统,就是JVM。位码文档(扩展名为.class的文档)就是JVM的可执行文件。JVM负责java程序的各种资源管理。

了解java三大平台及区分JDK与JRE

java根据应用领域的不同,区分为java SE、java EE与java ME三大平台。java SE是各应用平台的基础,分为4个主要部分:JVM、JDK、JRE和java程序语言。JDK包括java程序语言、JRE与开发工具包;Java Runtime Environment就是java执行环境,简称JRE,包括Java SE API、JVM与部署(Deployment)技术。部署技术就是将程序安装到客户端的技术。Java SE API涵盖了各式常用的链接库,像是通用的集合(Collection)、输入/输出、连接数据库的JDBC,撰写窗口程序的AWT与Swing等,这些都是在各个JSR标准文件的规范之中。

安装JDK时,JDK本身附带了Private JRE,主要是开发java程序时测试之用。与Public JRE的主要差别,就在于JDK本身附带的Private JRE比Public JRE多了个server的VM(Virtual Machine)的执行选项。server与client选项的差别在于使用的VM不同,执行java客户端程序时默认会使用Client VM,使用较少的内存以便取得较快的启动速度(因为客户端程序,通常想要较快的画面响应);使用server VM会花费较长的启动时间及耗费较多的内存,为的是启动java程序后获得较好的执行效能。安装Public JRE只不过是方便有另一个JRE来模拟客户端的Public JRE环境。

JDK安装好的文件夹中,bin中存放的就是“开发工具”选项;demo与sample存放的就是“演示程序及样例”选项;jre则是JDK中的Private JRE(不是安装选项中的Public JRE);src.zip则是“源代码”选项,也就是java SE API的运行原始码。无论是Private JRE还是Public JRE的文件夹中,都有一个lib的目录,其中有个rt.jar文档,JAR(Java Archive)文档是zip压缩格式,解压打开后就能看到java SE API编译好的.class文件。

撰写一个简单java程序的步骤:

1. 定义类

      class是用来定义类的关键词,之后接上类名称(HelloWorld)。java程序规定,所有程序代码都要定义在类中。class前有个public关键字,表示HelloWorld类是公开类。一个.java文档可以定义多个类,但只能有一个公开类,而且主文档名必须与公开类的类名称相同。

2. 定义区块(Block)

     在程序中使用大括号“{“与”{“定义区块,大括号两两成对,目的在于区别程序代码范围。

3. 定义main()方法

程序执行的起点就是程序进入点(Entry Point),java程序执行的起点是main()方法。规格书中规定main()方法的形式必须是:

public static void main(String[] args){}

注:

main()是public成员,表示可以被JVM公开的执行;

static表示JVM不用生成类实例(新建对象)就可以调用,java程序执行过程中的错误,都是以例外方式处理,所以main()不用传回值,声明为void即可;

String[] args 可以在执行程序时,取得用户指定的命令行自变量。

4. 撰写描述(statement)

描述就是程序语言中的一行指令,简单来说,就是程序语言中的“一句话”。注意每句描述的结束要用分号“;”。

例如:

System.out.println(“Hello World”);

这句描述的作用就是请系统的输出装置显示一行文字“Hello World”。

注:

其实这句描述是调用了java.lang包(package)中System类的public static成员out,out参考至printStream的实例,调用PrintStream定义的println()方法,将指定的字符串(String)输出至文本模式上;println()表示输出字符串后自动换行,如果使用print()输出字符串后不会换行。

了解与设定PATH、CLASSPATH、SOURCEPATH等环境变量

1、PATH是什么

*.java 必须编译为 *.class ,才可以在JVM中执行,java的编译程序工具程序是javac;装好JDK后,工具程序就会放在JDK安装文件夹的bin文件夹下。

可以打开“命令提示符”模式,切换到JDK目录下,并执行 javac 指令,javac 编译成功后就会悄悄的结束,如果没看到信息就是编译成功,否则就是编译失败。

当你输入一个指令而没有指定任何路径信息时,操作系统会依照PATH环境变量中设定的路径顺序,依次寻找各路径下是否有这个指令。可以执行echo %PATH%来查看目前操作系统PATH环境变量中包含的路径信息。如果输入java或javac指令后,系统找完PATH中所有路径后,未找到java或javac(.exe)工具程序,当所有的路径都找不到指定的工具程序后,就会报错。

要在path中设定工具程序的路径信息,系统才可以在path的路径下找到你想要执行的指令。如果要设定PATH,可以使用SET来设定,设定方式为SET PATH=路径信息;设定时若有多个路径信息,可用分号(;)隔开,通常会将原有的PATH附加在设定值后面,这样寻找其他路径时,才可以利用原有的PATH信息。设定完成后就可以执行java或javac指令,而不用额外的指定路径(不过在“命令提示符”中设定路径关闭后,下次再打开“命令提示符”模式又得重新设定,为了方便,还是右键“计算机”选择“属性”中的“环境变量”来增加设定吧)。

建议将JDK的bin路径设定到PATH变量的最前方,因为系统搜索路径是从最前方开始的,若是找到指定的工具程序就会直接执行。当系统中安装两个以上的JDK时,PATH路径中JDK的bin路径设定的顺序,会执行最前方的JDK工具程序。

2、JVM(java)与CLASSPATH

启动JVM的指令是java,而要求JVM执行Hello World时,只要在 javac 后面指令类名称就可以了,不用附加.class扩展名,附加.class反而会有错误信息。

想要JVM执行某个可执行文件(.class),就要告诉JVM到哪个路径下寻找.class文档,方式是通过CLASSPATH来设定可执行文件(.class)的路径信息。

JVM会依照CLASSPATH路径顺序,搜索是否有对应的类文档。

PATH与CLASSPATH是不同层次的环境变量,实际操作系统搜索的可执行文件(.exe,.bat)是看PATH路径,JVM搜索可执行文件(.class)只看CLASSPATH。

CLASSPATH 其实是给应用程序类加载器(AppClassLoader)使用的信息。

3、编译程序(javac)与CLASSPATH

javac 等工具程序,大多也是java撰写的,执行在JVM上。所以使用javac 编译程序时,也需要在CLASSPATH中指定路径信息。

4、编译程序(javac)与sourcepath

在编译时,首先会搜索-sourcepath指定的文件夹是不是有使用到的类原始码,然后会搜索classpath中,是否有已编译的类位码。确定原始码与位码搜索路径后,检查classpath中是否有已经编译完成的.class文件,如果存在且上次编译后类位码文档没有改变,则无需重新编译;如果不存在.class文件,则重新编译原始码。

在实际项目中会有数以万计的类,如果每次都要重新将.java编译为.class,那会是非常费时的工作,所以编译时若类路径中已存在位码,且上次编译后原始码并没有修改,无须重新编译会比较节省时间。

可以在编译时指定-verbose自变量,看到编译程序在编译的过程,有助于了解classpath与sourcepath的区别。

上一篇:《java JDK7 学习笔记》之继承与多态


下一篇:java中newInstance和new(转)