Java平台概述(上)
版本演进
- 开发者版本 JDK(全名Java Development Kits)。
- 平台版本 Java 2 Platform,根据不同的体系架构分为三大平台:标准版J2SE、企业J2EE和微型版J2ME。
- 版本号由1.5跳到5.0,表示该版本的重要性。
- 从版本6后,取消2这个号码,即Java Platform,J2SE、J2EE和J2ME分别更名为 Java SE、Java EE和Jave ME。JDK全名改为Java SE Development Kits。
- Oracle并购Sun后,先后发布版本7和8。所有的http://java.sun.com/都会跳转到http://www.oracle.com/technetwork/java/下。
Java SE
下图为Java SE 8的组成概念图:
Java SE可分为四个主要部分:
JVM(Java Virtual Machine)
Java原始码(.java)编译时,并不直接编译为相依于某平台的0、1序列,而是翻译为中介格式的位码(.class)。Java程序只能在JVM上运行,JVM的可执行文件是位码文档(.class)
。
不同平台安装专属该平台的JVM后,实现“编译一次,到处执行”跨平台的目的。
JRE(Java SE Runtime Environment)
只用于执行Java程序。
包括JVM
、Java SE API
和部署技术
。
JDK(Java SE Development Kits)
用于开发Java程序,包括执行。
包括JRE
、工具程序
(javac、javadoc、javap等)和Java语言程序
。
Java语言
略
JDK配置详解
以jdk-8u45-windows-x64.exe为例,这是JDK 8发布以来的的第45个修正版。
将JDK安装在“E:\jdk1.8.0_45”,将公共JRE安装“E:\jre1.8.0_45”。现在查看JDK的文件夹:
开发工具
就是用于编译程序之类的工具程序,对应着bin文件夹。源代码
指的是JRE中Java SE API的原始码,对应着src.zip这个文件,而其位码则在JRE的lib\rt.jar。公共JRE
是相对于JDK本身附有的Private JRE(对应着jre文件夹)而言。Private JRE主要是开发Java程序时测试之用,Public JRE可方便模拟客户端的Public JRE环境。
1称对版本7,二者的差别是Private JRE有server和client选项(见bin文件夹),Public JRE只有client选项。执行Java客户端程序会默认使用client VM,以较少内存取得较快的启动速度,而使用server VM会花较长的启动时间及耗用较多的内存,为的是启动Java程序后可以获得较好的执行效能,通过java -server启动。
JRE的lib文件夹中放着Java SE API和部署技术。
通过对JDK各文件的对应,进一步印证了JDK的组成:JRE、工具程序和Java语言程序。
如果安装公有JRE(像个小白客户一样),会发现PATH环境变量被加了“C:\ProgramData\Oracle\Java\javapath;”,且该文件夹下有java.exe、javaw.exe和javaws.exe(C:\Windows\System32也有),因此可以直接使用java指令(启动JVM执行Java程序)。
但是安装JDK意味着你要开发,肯定不能是小白,Java阵营的哲学是假设你懂得准备相关开发环境,因此装好JDK之后,该自己设定的变量或选项就要自己设定,JDK不会代劳。
PATH
“命令提示符”模式中,当输入一个可执行文件(.exe、.bat)
,Win操作系统进行搜索:
- 如果指定了完整路径搜索结束
- 否则, 操作系统查找当前目录
* 如果找到,搜索结束 * 否则,按照PATH环境变量中设定的路径顺序,依次寻找各路径,搜索结束
搜索优先级:
- 完整路径
- 当前目录
- PATH环境变量
例如:
(1).编辑
添加E:\test\Helloworld.java文件。1
2
3
4
5class Helloworld{
public static void main(String args[]){
System.out.println("Hello World");
}
}
(2).编译
使用Java的编译工具程序javac sourcefile,指定完整路径。1
$ "E:\jdk1.8.0_45\bin\javac" "E:\test\Helloworld.java"
当把“E:\Java\jdk1.8.0_45\bin\”加入PATH环境变量中,这样不论切换至哪,都可以直接使用JDK的工具程序。1
$ javac "E:\test\Helloworld.java"
(3).执行
在编译后生成了E:\test\Helloworld.class,执行语句为1
$ java -cp E:\test Helloworld
而不是$ java "E:\test\Helloworld"
,原因在于JVM搜索 .class不是用完整路径,而是用-cp
。
注:本文以完全路径撰写,相对路径可促类旁通。
■
CLASSPATH
通过CLASSPATH告诉JVM如何搜索可执行文件(.class)的路径。这就类似于通过PATH告诉Win操作系统如何搜索可执行文件(.exe、.bat)的路径。
“命令提示符”模式中,当需要用到一个可执行文件(.class)
,JVM进行搜索:
- 如果指定了路径(自变量-classpath或-cp),搜索结束
- 否则, 操作系统查找当前目录
* 如果找到,搜索结束 * 否则,按照CLASSPATH环境变量中设定的路径顺序,依次寻找各路径,搜索结束
搜索优先级:
- 指定路径(自变量-classpath或-cp)
- 当前目录
- CLASSPATH环境变量
所谓需要用到的时候,可以是执行,也可以是编译,比如编译一个类的原始码依赖于另一个现成的类的位码。
例如:
(1). 编辑
现在另外引用一个E:\test\classes\Console.class,并对E:\test\Helloworld.java进行改写。1
2
3
4
5class Helloworld{
public static void main(String args[]){
Console.writeLine("Hello World");
}
}
(2). 编译
如果直接编译Helloworld.java的话,显然编译程序认不得 并不是 Java SE API的Console类,就需要告诉编译程序Console.class的位置是在classes目录下。用-verbose自变量,可看到过程信息。1
$ javac -cp E:\test\classes -verbose "E:\test\Helloworld.java"
输出:
源文件的搜索路径:E:\test\classes
类文件的搜索路径:E:\jdk1.8.0_45\jre\lib\resoureces.jar,……,E:\test\classes
正在加载Object.class,……,E:\test\classes\Console.class
已写入E:\test\Helloworld.class
可见,编译程序搜索并加载了Helloworld.java所需的链接库,最后写入Helloworld.class,完成编译。值得注意的是,的确使用了JDK的Private JRE。
(3). 执行
执行Helloworld.class,必须指定Helloworld.class和Console.class的位置,前者在当前目录下,后者在classes目录下。1
$ java -cp E:\test;E:\test\classes -verbose Helloworld
输出:
Opened E:\jre1.8.0_45\lib\rt.jar
Loaded java.lang.Object,…… from E:\jre1.8.0_45\lib\rt.jar
Loaded Console from file:/E:/test/classes/
可见,在打开并加载了Java SE API的位码后,还加载了Console.class,实现对Helloworld.class的执行。
补充:用哪个JRE是取决于在PATH中先出现是%JRE%还是%JDK%。在PATH中找到第一个java可执行文件后,按照顺序
- 当前目录是否有原生链接库
- 上一层目录是否有jre目录
来确定用哪个JRE。而我的是%JRE%在前%JDK%在后,所以用的是Public JRE。如果%JDK%在前,java命令就会用Private JRE。■