Java从入门到精通(第4版)

978-7-115-56338-5
作者: 宁跃飞史卫亚张洪超
译者:
编辑: 张天怡
分类: Java

图书目录:

详情

本书以零基础讲解为宗旨,用实例引导读者学习,深入浅出地介绍了Java的相关知识和实战技巧。 本书“第Ⅰ篇 基础知识”主要介绍Java开发环境搭建、Java程序要素、常量、变量、数据类型、运算符、表达式、语句、流程控制、数组、枚举、类、对象以及方法等,“第Ⅱ篇 核心技术”主要介绍类的封装、继承、多态、抽象类、接口、Java常用类库以及异常的捕获与处理等,“第Ⅲ篇 高级应用”主要介绍多线程、文件I/O操作、GUI编程、数据库编程、Java Web以及常用设计框架等,“第Ⅳ篇 项目实战”主要介绍中国象棋和我的饭票网等项目。此外,附赠的电子书中还介绍了Android编辑基础、Hadoop下的数据处理、全分布式Hadoop集群的构建等内容。 本书提供了与图书内容全程同步的视频教程,还赠送了大量相关学习资料,以便读者配合学习。 本书适合任何想学习Java的读者,无论你是否从事计算机相关行业,是否接触过Java,均可通过学习本书快速地掌握Java的开发方法和技巧。

图书摘要

版权信息

书名:Java从入门到精通(第4版)

ISBN:978-7-115-56338-5

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。


版  权

编  著 宁跃飞 史卫亚 张洪超

责任编辑 张天怡

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315

内 容 提 要

本书以零基础讲解为宗旨,用实例引导读者学习,深入浅出地介绍了Java的相关知识和实战技巧。

本书“第Ⅰ篇 基础知识”主要介绍Java开发环境搭建、Java程序要素、常量、变量、数据类型、运算符、表达式、语句、流程控制、数组、枚举、类、对象以及方法等,“第Ⅱ篇 核心技术”主要介绍类的封装、继承、多态,抽象类,接口,Java常用类库以及异常的捕获与处理等,“第Ⅲ篇 高级应用”主要介绍多线程、文件I/O操作、GUI编程、数据库编程、Java Web以及常用设计框架等,“第Ⅳ篇 项目实战”主要介绍中国象棋和我的饭票网等项目。此外,附赠的电子书中还介绍了Android编程基础、Hadoop下的数据处理、全分布式Hadoop集群的构建等内容。

本书提供了与图书内容全程同步的视频教程,还赠送了大量相关学习资料,以便读者配合学习。

本书适合任何想学习Java的读者,无论你是否从事计算机相关行业,是否接触过Java,均可通过学习本书快速地掌握Java的开发方法和技巧。

前  言

“从入门到精通”系列是专为初学者量身打造的一套编程学习用书,由知名计算机图书策划机构“龙马高新教育”精心策划而成。

本书主要面向Java初学者和爱好者,旨在帮助他们掌握Java基础知识、了解Java开发技巧并积累一定的项目实战经验。

为什么要写这样一本书

荀子曰:“不闻不若闻之,闻之不若见之,见之不若知之,知之不若行之”。

实践对于学习的重要性由此可见一斑。纵观当前编程图书市场,理论知识与实践经验脱节是某些Java图书中经常出现的情况。针对这一问题,本书立足于实战,从项目开发的实际需求入手,将理论知识与实际应用相结合,目的就是让初学者能够快速成长为初级程序员,并积累一定的项目开发经验,从而在职场中拥有一个高起点。

Java的学习路线

本书总结了笔者多年的教学实践经验,为读者设计了学习路线。

本书特色

● 零基础、入门级的讲解

无论读者是否从事计算机相关行业,是否接触过Java,是否使用Java开发过项目,都能从本书中获益。

● 超多、实用、专业的范例和项目

本书结合实际工作中的范例,逐一讲解Java的各种知识和技术;最后还以实际开发项目来总结本书所学内容,帮助读者在实战中掌握知识,轻松获得项目经验。

● 随时检测自己的学习成果

每章首页给出了“本章要点”,以便读者明确学习方向。每章最后的“实战练习”则根据所在章的知识点精心设计而成,读者可以随时进行自我检测,巩固所学知识。

● 细致入微、贴心提示

本书在讲解过程中使用了“提示”“注意”等小栏目,以帮助读者在学习过程中更清楚地理解基本概念、掌握相关操作,并轻松获取实战技巧。

超值资源

● 全程同步教学录像

录像涵盖本书所有知识点,详细讲解每个范例及项目的开发过程与关键点,帮助读者更轻松地掌握书中所有的Java程序设计知识。

● 超多资源大放送

赠送大量资源,包括Java和Oracle项目实战教学录像、Java SE类库查询手册、Eclipse常用快捷键说明文档、Eclipse提示与技巧电子书、Java常见面试题、Java常见错误及解决方案、Java开发经验及技巧大汇总、Java程序员职业规划、Java程序员面试技巧。

读者对象

二维码视频教程学习方法

为了方便读者学习,本书提供了大量视频教程的二维码。读者使用微信、QQ的“扫一扫”功能扫描二维码,即可通过手机观看视频教程。

创作团队

本书由宁跃飞、史卫亚和张洪超编著,其中第0~第10章由郑州升达经贸管理学院宁跃飞老师编著、第11~第17章由河南工业大学史卫亚老师编著,第18~21章及附录由张洪超老师编著。

在本书的编写过程中,我们竭尽所能地将最好的讲解呈现给读者,但书中仍难免有疏漏和不妥之处,敬请广大读者不吝指正。若读者在阅读本书时遇到困难或产生疑问,或有任何建议,可发送邮件至zhangtianyi@ptpress.com.cn。

读者可以申请加入编程语言交流学习群(QQ:829094243),在群中可以获得本书的学习资料,并和其他读者进行交流,从而无障碍地快速阅读本书。

编者

赠送资源

❶ Java和Oracle项目实战教学录像

❷ Java SE类库查询手册

❸ Eclipse常用快捷键说明文档

❹ Eclipse提示与技巧电子书

❺ Java常见面试题

❻ Java常见错误及解决方案

❼ Java开发经验及技巧大汇总

❽ Java程序员职业规划

❾ Java程序员面试技巧

第0章 Java学习指南

Java是一门面向对象的语言,它简洁高效,具有高度的可移植性。本章介绍Java的来源、基本思想、技术体系、应用领域和前景以及学习Java的技术路线。

本章要点(已掌握的在方框中打钩)

了解Java的来源

了解Java的基本思想

了解Java的技术体系、应用前景

0.1 Java为什么重要

目前,常用的编程语言就有数十种,那么到底哪一种语言最值得我们学呢?要知道,学习任何一种语言,都需付出昂贵的时间成本(甚至金钱成本),因此如何选择一种真正需要的编程语言来学,就是一门学问了。

在现实生活中,有个很有意思的经验。当我们来到一个陌生的城市,自然想找一家比较有特色的饭馆打打牙祭,但面对街头各式各样的饭馆,选择哪家最好呢?有人说,哪家人少去哪家,因为这样不用等啊!但有经验的“吃货”会告诉你,哪家人多,特别是等的人多,就去哪家。为什么呢?逻辑很简单,之所以人多,是因为好吃;之所以等的人多,是因为它值得人等。一句话,大样本得出的推荐建议,总还是比较让人信得过的。

对于初学者来说,编程语言的选择犹如饭馆的挑选——追随多数人的选择,纵然可能没有满足你个性化的需求,但绝对不会让你错得离谱。既然我们现在正处于大数据的时代,就要善于“让数据发声”。

如下图所示,根据TIOBE统计的数据,在2019年1月编程语言前10名排行榜中,Java名列榜首。虽然在不同的年份,Java与C语言和C++的前3名地位可能有过互换,但多年来,Java在整个编程领域前三甲的地位,基本没有被动摇过。

Java作为一门编程语言,其关注度长期高居各种编程语言流行榜的榜首,这也间接说明了Java应用领域的广泛程度。事实上,Java的开放性、安全性和庞大的社会生态链以及其跨平台性,使得Java技术成为很多平台的开发标准。在很多应用开发中,Java都作为底层代码的操作功能的调用工具。

当下,不论是桌面办公还是网络数据库,不论是PC还是嵌入式移动平台,不论是Java小应用程序(Applet)还是架构庞大的Java EE企业级解决方案,处处都有Java的身影。

目前,随着云计算(Cloud Computing)、大数据(Big Data)时代的到来以及人们朝着移动领域的扩张,越来越多的企业考虑将其应用部署在Java平台上。无论是面向智能手机的Android开发,还是支持高并发的大型分布式系统开发;无论是面向大数据批量处理的Hadoop开发,还是解决公共云/私有云的部署,都和Java密不可分,Java已然形成一个庞大的生态系统。

此外,Java的开放性也对打造其健壮的生态系统贡献非凡。基本上,无论我们有什么新的想法,都可以在Java的开源世界中找到对应的实现,而且其中很多解决方案还非常靠谱,例如与服务器相关的Tomcat,与计算框架相关的Hibernate、Spring和Struts,与大数据处理相关的ZooKeeper、Hadoop和Cassandra,等等。有了基于Java开发的开源软件,程序员们就不用从零开始“重造轮子”,这样就大大减轻了开发组的负担,提高了解决问题的效率。

坦率来说,对于很多计算机相关领域的从业人员,找份好工作是学习某门编程语言的驱动力。而Java应用领域之广泛,也势必促使面向Java程序员的就业市场呈现欣欣向荣之态势。根据国际数据公司(International Data Corporation,IDC)的统计数据,在所有软件开发类人才的需求中,对Java工程师的需求占比达到60%~70%。这一高分值数字,足以让Java初学者跃跃欲试。

一言蔽之,学好用好Java,可以解决诸多领域的问题,这就是Java如此重要的原因。

0.2 Java简史——带给我们的一点思考

著名人类学家费孝通先生曾指出,我们所谓的“当前”,其实包含着从“过去”历史中拔萃出来的投影和时间选择的积累。历史对于我们来说,并不是什么可有可无的点缀之饰物,而是实用的、不可或缺的前行之基础。

Java从诞生(1995年)发展到现在,已经过去了20多年。了解Java的一些发展历史,有助于我们更好地认识Java,看清这纷杂的编程语言世界,进而用好Java。

说到Java的发展历程,就不能不提到它的新老两个东家——Sun(中文译为“太阳”)公司和Oracle(中文译为“甲骨文”)公司。先说Sun公司,事实上,Sun的本意并非是指“太阳”,而是指斯坦福大学校园网(Stanford University Network)的首字母缩写,跟“太阳”并没有关系。不过,由于这个缩写的蕴意不错,“太阳”就这样被叫开了。

1982年,Sun公司在斯坦福大学产业园“孵化”出来,后来成为一家大名鼎鼎的高科技IT公司,其全称是太阳微系统(Sun Microsystems)公司。Sun公司的主要产品是服务器和工作站,其产品极具竞争力,在自然市场成绩斐然。在硬件方面,公司于1985年研制出了自己的可扩充处理器架构(SPARC)精简指令集计算机(RISC)微处理器,能将服务器的性能提高很多;在软件方面,公司引以为傲的Solaris操作系统(UNIX的一个变种)比当时的Windows NT能更好地利用计算机资源,特别是在用户数量急剧上升、计算机系统变得非常庞大的情况下,Solaris的表现更佳。

20世纪90年代,互联网兴起。Sun公司就站在那个时代的潮流之上,所以它的服务器和工作站销量极佳,以至于这家公司在自己的广告中宣称:“我们就是.com前面的关键一点(We are the dot in the .com)。”言外之意,没有我们这画龙点睛的一点(服务器+操作系统),互联网公司就难以开起来。

Sun公司之所以敢于高抬自己,并不是吹嘘,它的实力的确非常雄厚,在当时足以傲视群雄。公司重要的软实力,就是人才济济。在任何年代,人才都是稀缺的(不光是21世纪)。

Sun公司创始人之一斯科特·麦克尼利(Scott McNealy)可谓一代“枭雄”,他非常重视研发。在他的主持下,Sun公司先后开发了基于SPARC系列的处理器、工作站和Solaris操作系统,这些产品为Sun公司带来了丰厚的利润。

但如果我们把格局放大一些的话,从科技史的角度来看,可能Sun公司给人类带来的最有意义的产品并不是前面提及的软件和硬件,而是我们即将要介绍的重要内容——Java编程语言。

现在让我们简单地回顾一下Java诞生的背景。在20世纪90年代,世界上的计算机大多处于两种状态:要么孤零零地“宅着”——不联网;要么小范围地“宅着”——企业内部局域网互联。那时可供公众分享的资源是非常有限的。

后来,随着互联网的蓬勃发展,就产生了不同类型的计算机系统相连接和信息共享的需求,亟需一种可跨越不同硬件和不同操作系统的新平台——这就是那个时代的“痛点”。任何时候,谁能解决时代的痛点,就意味着谁研制出了划时代的产品;谁能解决时代的痛点,就表明谁抓住了时代的发展方向。

Sun公司的创始人之一麦克尼利对网络计算有着超前的洞察力。在他的带领下,Sun公司的网络视野并未仅仅定格于计算机之间的互联,而是看得更远——计算机与非计算机彼此也是隔断的,它们也需要彼此连接!

在Sun公司,麦克尼利一直在推行“网络即计算机(The network is the computer)”的理念。这个关于无限连通世界的理念的表述,推动着Sun公司参与时代的发展。事实上,这个理念和现在大热的云计算理念也是一脉相承的。

2016年4月28日,全球移动互联网大会(Global Mobile Internet Conference,GMIC)在北京举行,当时的腾讯副总裁程武发表了《共享连接的力量》主题演讲。他提到,3年前,腾讯就提出“连接一切”的理念。无论连接人与人、人与服务,还是人与设备,互联网从根本上是在满足人的延伸需求,让网络中的个体获得更多的资源和能力,去实现更大的价值。

这样的认知其实是梅特卡夫定律(Metcalfe's Law)的体现,其内容是,网络的价值等于网络节点数的二次方,网络的价值与联网的用户数的二次方成正比。梅特卡夫认为,“连接”革命后,网络价值会飙升,网络中的个体有望实现更大的价值。

回顾起来,不论是现在流行的物联网(Internet of Things,IoT)概念,还是腾讯的“连接一切”理念,其实和Sun公司30多年前的理念都相差无几。因此可以说,Sun公司在那个时代的视角,不可谓不“高瞻远瞩”。

Sun公司认为,如果能把计算机和非计算机(主要指的是电子消费品,如家电等)系统这两者连接起来,将会带来一场计算机革命,这是一个巨大的机遇,而连接二者的媒介自然就是网络。

无限连通的世界,令人心动不已。但心动不如行动。Sun公司行动的结果,就是Java语言的诞生。

后来被称为Java之父的詹姆斯·戈斯林(James Gosling,又译为詹姆斯·高斯林)说:“放眼当时的市场,两个领域的厂家各自为政,没有形成统一的网络。因此很多时候人们不得不重复大量的实验,但这些问题其实早在30年前的计算机科学中已得到解决。”

其实核心问题在于,当时的电子消费品制造者压根就没有考虑使用网络,例如没有哪家生产商想生产一台会上网的冰箱。一流的企业,如苹果公司,是引导用户需求,而不是满足用户需求。因为有时候用户压根就不能明确自己的需求。

为了解决计算机与计算机之间、计算机与非计算机之间的跨平台连接,麦克尼利决定组建一个名叫Green的、由詹姆斯·戈斯林领衔的项目团队。该团队的目标是开发一种新的语言,并基于这种语言,研制专供下一代数字设备(如家电产品)和计算机使用的网络系统,这样就可以将通信和控制信息通过分布式网络发给电冰箱、电视机、烤面包机等家用电器,对它们进行控制和信息交流。想一想,这不正是当下很热门的物联网思维吗?

最初Green项目的工程师们准备采用C++实现这一网络系统。但C++比较复杂,最后经过裁剪、优化和创新,1990年,詹姆斯·戈斯林的研发小组基于C++开发了一种与平台无关的新语言Oak(即Java的前身)。Oak的名字源于詹姆斯·戈斯林办公室外的一棵枝繁叶茂的橡树,这在硅谷是一种很常见的树。

Oak主要用于为各种家用电器编写程序,Sun公司曾以Oak语言投标一个交互式电视项目,但结果被SGI(硅图公司,1982年成立于美国)打败。由于当时智能化家电的市场需求比较低迷,Oak的市场占有率并没有当初预期的高,于是“见风使舵”的Sun公司放弃了该项计划(事实上,“见风使舵”在市场决策中并不是一个贬义词,而是一种灵活的市场策略)。就这样,Oak几近“出师未捷身先死”。其实也不能全怪Sun公司,想一想,即使在30多年后的今天,物联网、智能家居的概念虽然很火,但接地气、成气候的项目屈指可数。

恰逢这时,Mark Ardreesen(美国软件工程师,曾创办网景通信公司)开发的Mosaic浏览器(互联网历史上第一个被普遍使用且能够显示图片的网页浏览器)和Netscape浏览器(网页浏览器,曾在市场中占据主导地位)启发了Oak项目组成员,让他们预见到Oak可能会在互联网应用上“大放异彩”,于是他们决定改造Oak。

项目组及时调整战略,把握住了时代的需求,于是Oak迎来了自己的“柳暗花明又一村”。也就是说,由于计算机与非计算机之间的连接这一想法太超前,Oak失败了,但是计算机与计算机之间的连接需求(更加接近那个时代的地气)又救活了Oak。

1995年5月23日,Oak改名为Java。至此,Java正式宣告诞生。Oak之所以要改名,其实也是情非得已,因为Oak作为一个商标,早已被一家显卡制造商注册了。Oak若想发展壮大,在法律层面上,改头换面势在必行。

其实Java本身也寓意十足,它是印度尼西亚的爪哇(注:Java的音译)岛的英文名称,该岛因盛产咖啡而闻名。这也是Java官方商标为一杯浓郁的咖啡的背后原因,而咖啡也是“爱”加班、“爱”熬夜的程序员们提神的最佳饮品之一,如下图所示。

Java标志

当时,Java最让人着迷的特性之一,就是它的跨平台性。在过去,计算机程序在不同的操作系统平台(如UNIX、Linux和Windows等)上移植时,程序员通常不得不重新调试与编译这些程序,有时甚至需要重写。

Java的优点在于,在设计之初就秉承了“一次编写,到处运行”(Write Once, Run Everywhere,WORE;有时也写成Write Once, Run Anywhere,WORA)的思想,这是Sun 公司为宣传Java语言的跨平台特性而提出的口号。

传统的程序通过编译可以得到与各种计算机平台紧密耦合(Coupling)的二进制代码。这种二进制代码可以在一个平台运行良好,但是换一个平台就“水土不服”,难以运行。

而Java的跨平台性,是指在一种平台下用Java语言编写的程序,在编译之后不用经过任何更改就能在其他平台上运行。例如,一个在Windows环境下开发出来的Java程序,在运行时,可以无缝地部署到Linux、UNIX或macOS环境之下;反之亦然,在Linux环境下开发的Java程序,同样可在Windows等其他平台上运行。Java是如何实现跨平台的呢?我们可用下面的图来比拟说明。

例如中国人(一个平台)说了一句问候语:“你好,世界!”美国人、法国人、德国人及日本人(其他平台)都能理解中国人的“问候”。之所以这样,是因为英语、法语、德语及日语翻译们进行了翻译。

Java的聪明之处在于,它用一个名为Java虚拟机(Java Virtual Machine,JVM)的机制屏蔽了这些“翻译”的细节。各国人尽管尽情地表达(编写Java代码),因为他们的“表达”经过编译,会形成各个平台通用的字节码(Byte Code),然后JVM“看平台下菜”,在背后默默地干起了“翻译沟通”的活。正是因为有JVM的存在,Java程序员才可以做到“一次编写,到处运行”——这也是Java的精华所在。

在经过一段时间的Java学习后,读者就会知道由Java源码编译出的二进制文件叫类(Class)文件,如果使用十六进制编辑器(如UltraEdit等)打开这个Class文件,你会发现这个文件最前面的32位将显示为“CA FE BA BE”,连接起来也就是词组“CAFE BABE ”(咖啡宝贝),如下图所示。每个Class文件的前4个字节都是这个标识,它们被称为“魔数”,主要用来确定该文件是否为一个能被JVM接受的Class文件。其另外一个作用就是,让诸如詹姆斯·戈斯林这类具有黑客精神的编程天才尽情表演,他们就是这样,在这些不经意的地方“雁过留声,人过留名”。

或许,麦克尼利看到了Java的这一优秀特性,在Java推出以后,Sun公司便赔钱做了大量的市场推广。仅3个月后,当时的互联网娇子之一——网景公司,便慧眼识珠,决定采用Java。

由于Java是新一代面向对象的程序设计语言,不受操作系统限制,在网络支持方面很强,加之对终端用户是免费的,因此它一下子就火了。很快,很多大公司如Oracle、Borland、SGI、IBM、AT&T和Intel等都纷纷加入了Java阵营。当Java逐渐成为Sun公司的标志时,Sun公司索性就把它的股票代码“SUNW”直接改为了“JAVA”。Sun公司对Java的重视程度,由此可见一斑。

1997年,Sun公司推出64位处理器,同年推出Java 2,Java渐渐风生水起,市场份额也越做越大。1998年,Java 2 按适用的环境不同,分化为4个派系(见下图):Java 2 Micro Edition(Java ME)、Java 2 Standard Edition(Java SE)、Java 2 Enterprise Edition(Java EE)以及Java Card。ME的意思是小型设备和嵌入系统,这个小小的派系,其实是Java诞生的“初心”。

(1)标准版(Standard Edition,Java SE):支持面向桌面级应用(如Windows操作系统下的应用程序)的Java平台,提供了完整的Java核心API(Application Programming Interface,应用程序接口),这个版本2005年以前被称为J2SE。

(2)企业版(Enterprise Edition,Java EE):以Java SE为基础向外延伸,增加了许多支持企业内部使用的扩充类,同时支持使用多层架构的企业应用[如企业资源计划(ERP)系统、客户关系管理(CRM)系统的应用]的Java平台。除了提供Java SE API外,Java EE还对其做了大量的扩充并提供了相关的部署支持。这个版本2005年以前被称为J2EE。

(3)微型版(Micro Edition,Java ME):Java ME同样以Java SE为基础,但相对精简。它所支持的只有核心类的子集合,它支持Java程序运行在移动终端(手机、PDA——掌上电脑)上的平台,加入了针对移动终端的支持。这个版本2005年以前被称为J2ME。Java ME主要进行嵌入式开发,目前渐渐被Android开发所替代。

(4)智能卡版(Java Card):由于服务对象定位更加明确化,Java Card版本比Java ME更加精简。它支持一些Java小程序运行在小内存设备(如容量小于64KB的智能卡)的平台上。

但是Java的技术平台不管如何划分,都是以Java SE为核心的,所以掌握Java SE十分重要,这也是本书的主要讲解内容。如果想进行Java EE的开发,Java SE是其中必要的组成部分,这也是为什么在学习Java EE之前要求读者一定要有扎实的Java SE基础。

当时专为连接智能家电而开发的Java,不曾想“有心栽花花不开,无心插柳柳成荫”,在家电市场毫无起色,却因其“一次编程,到处运行”的跨平台特性,赶上了互联网的高速发展时机,在企业级市场上大放异彩。

Java ME一度在翻盖手机应用上得到极大推广,成为当时的标配。但后来随着Android的兴起慢慢中落。Java之父詹姆斯·戈斯林后来也说,“Java ME已经做得足够好了,在当时是最强大的智能电话开发平台之一。不过现在渐渐被遗忘,因为Android太耀眼了。”

有起有落,螺旋上升,是事物发展的常态。Java的发展历程也不例外。Oracle Java平台开发副总裁、OpenJDK管理委员会核心成员乔治·萨博(Georges Saab)曾经这样说道:“在20世纪90年代,大多数程序员都把精力投入桌面应用的编写之上。到了2000年,一家美国宠物网站的成功吸引了大批的跟风者。业界又把焦点从桌面转移到了超文本标记语言(Hyper Text Markup Language,HTML)应用。随着智能电话和平板电脑的到来,基于触摸屏的移动应用又站在了潮流前端。所以对于下一个流行趋势是我们很难把握的,这涉及天时、地利、人和。”

然而,Java对于Sun公司来说是“华而不实”的资产。因为除了带来日渐高涨的声誉外,Java并没有直接给Sun公司带来与其声誉对等的回报。用华尔街的话来说,Java是赔钱赚吆喝。吆喝Java是赚到了,但盈利赚钱才是生存之道。

现在具备互联网思维的公司都知道,“免费”的目的是不免费,不免费的对象要发生转移,其实是要让“羊毛出在猪身上”,最后“让狗来买单”。但那是30多年前,那时Sun公司还没有很强的互联网赚钱思维,它到“死”(被Oracle公司收购)都没有想明白,为什么抱着一个金饭碗,却要不到饭。

事实上,除了生产处理器、服务器和操作系统之外,Sun公司还开发了办公软件OpenOffice。1995年到2000年是Sun公司高速发展的时期。这期间互联网飞速发展,它曾经和Oracle公司共同提出了网络计算机(Network Computer,NC)的概念 ,主要就是指没有硬盘的计算机,其实也就是低价台式机,是瘦客户机(或称无盘工作站)。

但在2000年之后,网络泡沫破碎,绝大多数的“.com”公司都关门了,苟延残喘活下来的公司,也急刹车般停止了扩张采购。服务器市场一下子低迷起来,Sun公司这个当初意气风发誓要成为互联网公司的“关键一点”的公司,已经不再关键了。老的盈利点(服务器市场)不盈利了,新的盈利点(如Java市场)又找不到,Sun公司突然陷入风雨飘摇的境地。

有道是“月满则亏,水满则溢”。Sun公司从1982年成立到2000年达到顶峰,用了将近20年,而走下坡路只用了一年。这种断崖式的毁灭,足以让今天的创业者引以为戒。

2008年爆发的金融危机,让持续亏损的Sun公司雪上加霜。到了2009年,由于业绩不佳,Sun公司的市值又比2007年下降了一半,终于跌到了对它觊觎已久的Oracle公司买得起的价格。2009年4月,市值曾经超过2000亿美元的Sun公司,在最低潮的时候,以74亿美元的便宜价被Oracle公司收购,这个价格仅仅为Sun公司顶峰市值的3%。作为Sun公司的核心资产之一的Java,自然也换了新东家——Oracle公司。

按照Oracle公司的老板拉里·埃里森(Larry Ellison,又译为拉里·埃利森)的话讲,Sun公司有很好的技术,也有很好的工程师,但它们的管理层实在是太烂了,而且做了很多错误的决策,这样才导致Oracle公司以很便宜的价格捡了漏[1]

[1] 原话是:Sun's management “made some very bad decisions that damaged their business and allowed us to buy them for a bargain price.”

2015年5月23日,在北京中关村3W咖啡屋,笔者参加了由Oracle(中国)公司举办的Java诞生20周年庆典。在概括Java成功的原因时,Oracle公司的开发人员关系团队总监Sharat Chander总结了3点:社区排在第一,这是Java成功的基础;Java技术的不断进步排在第二;而排在第三位的,才是Oracle公司对Java的管理。

在收购Sun公司后,Oracle公司一方面继续积极推动Java社区发展,另一方面及时将社区成果反馈、集成到新版本产品中。Oracle公司承诺,大型版本的更新每两年发布一次,小型版本的更新每6个月发布一次。

在版本推新上,Oracle公司极其尊重Java社区的意见,Java 7就是在与社区深入交流的基础上推出的,尽管当时并非推出Java 7的最好时机,其后续功能在Java 8里进行了补全。

对于Java的发展,的确不能忽视Java社区的重要性。Oracle公司认为自己并非Java的管家,他们是在与Java社区一起来管理Java,而Java社区也被誉为Java成功的基础。对此Sharat Chander介绍,Java社区拥有314个Java用户组、900多万名Java程序员、超过150个Java 技术领袖。

2009年12月,Java企业版的升级版Java EE 6发布。2011年7月28日,Java SE 7发布。

CPU多核时代的兴起,让程序员们纷纷探索起怎么编写并行代码。一番折腾后大家发现,很多编程的好思想都来自一个叫函数式编程的程序范式。这个曾被束之高阁的好理念又被人重拾起来。2014年3月19日,Oracle公司发布Java 8.0正式版,提供了令大家望眼欲穿的Lambda。

2017年9月22日,Java 9正式发布。Java 9的众多特性中比较引人注目的有两条。第一条:jshell(Java脚本运行环境)。这是Java 9新增的一个脚本工具,有了这个工具,类似于Shell或Python,用户可以在命令行里直接运行Java的代码,而无须创建Java文件,然后再编译、运行。第二条:模块化(Modularity)。模块化是Java 9的一个新特性。模块的实质就是在包(Package)之上再提炼一层,即用模块来管理各种包,从而可以让代码更加安全,因为它可以指定哪些部分隐藏起来,哪些部分暴露给外部。

2019年9月17日,Java 13正式发布。Java 13拥有众多特性,其中比较引人注目的有以下两条。

第一条:动态应用程序类数据共享。Java 13对Java 10中引入的应用程序类数据共享进行了进一步的简化、改进和扩展,允许Java应用程序执行结束时动态进行类归档。第二条:增强垃圾回收特性(ZGC)释放未使用内存。在 Java 13 中,ZGC 将向操作系统返回被标识为长时间未使用的页面,这样它们将可以被其他进程复用。同时释放这些未使用的内存给操作系统不会导致堆大小缩小到参数设置的最小大小以下,如果将最小和最大堆大小设置为相同的值,则不会释放任何内存给操作系统。

当然,Java也不是没有缺点。曾经有人采访C++之父Bjarne Stroustrup,问他如何看待Java的简洁,他的回答却是时间不够长。大师之见,果然深邃。Java之美,早已不是简洁,而是开发上的高效,其为之付出的代价是各种类库、框架异常复杂而臃肿。通常,即使是一个专业级的Java程序员,也需耗费不菲的(包括时间上或金钱上的)学习成本。但这符合事物的发展规律,就像我们不能在期望一个横纲级的相扑运动员力大无穷的同时又期望他身轻如燕。

这就是我们的Java!它不甚完美,却非常能干!

0.3 Java应用领域和前景

Java作为Sun公司推出的新一代面向对象的程序设计语言,特别适于互联网应用程序的开发,但它的平台无关性直接威胁到了Wintel(即Microsoft公司的Windows操作系统与Intel CPU所组成的个人计算机)的垄断地位,这表现在以下几个方面。

信息产业的许多国际大公司购买了Java许可证,这些公司包括IBM、Apple、DEC、Adobe、Silicon Graphics、HP、TOSHIBA以及Microsoft等。这一点说明Java已得到了业界的高度认可,众多的软件开发商开始支持Java软件产品,例如Inprise公司的JBuilder、Oracle公司自己维护的Java开发环境JDK与JRE。

Intranet正在成为企业信息系统最佳的解决方案,而Java将在其中发挥不可替代的作用。Intranet的目的是将Internet用于企业内部的信息类型,它的优点是便宜、易于使用和管理。用户不管使用何种类型的机器和操作系统,界面都是统一的Internet浏览器,而数据库、Web页面、Applet、 Servlet、JSP等则存储在Web服务器上,无论是开发人员、管理人员还是普通用户,都可以受益于该解决方案。

从桌面办公到网络数据库,从个人计算机到嵌入式移动平台,从Java应用小程序到架构庞大的Java EE企业级解决方案,处处都有Java的身影,就连美国国家航空航天局(NASA)的太空项目也使用了Java来开发控制系统和相关软件。

Java技术的开放性、安全性、庞大的社会生态链以及跨平台性,使其成为智能手机软件平台的事实性标准。在未来发展方向上,Java在Web、移动设备以及云计算等方面的应用前景也非常广阔。虽然面临来自网络的类似于Ruby on Rails这类编程平台的挑战,但Java依然还是事实上的企业Web开发标准。随着云计算、移动互联网、大数据的扩张,更多的企业考虑将其应用部署在Java平台上,那么无论是本地主机,还是公共云,Java都是目前最合适的选择之一。Java应用领域之广,也势必促使Java程序员的就业市场呈现欣欣向荣的发展态势。

学习Java不仅是学习一门语言,更多的是学习一种思想,一种开发模式。对从事软件行业的工作人员来说,掌握了Java语言,可以让自己日后的事业发展得更加顺利。Java语言的内容相对完整,因此Java开发人员可以轻松转入手机开发、.NET开发,以及PHP等语言的开发上,以后也可以更快地跨入项目经理的行列。

目前,市场对Java开发人才的需求旺盛。根据国际数据公司的统计数字,在所有软件开发类人才的需求中,对Java工程师的需求达到全部需求量的60%~70%。同时企业提供的薪水也非常丰厚,通常来说,具有3年以上开发经验的工程师,年薪10万元以上是一个很正常的薪酬水平。但IT企业很难招聘到合格的Java人才。所以读者朋友如果想让自己成为合格的、受企业欢迎的Java工程师,需要做好自己的职业发展规划。

首先,要定位自己的目标,然后再有的放矢地进行自我提升。对于Java工程师来说,大致可以从3个大方向来规划自己的职业蓝图。

(一)继续走技术工作之路

从技术发展方向来看,Java工程师可以由最初的初级软件工程师(即程序员)逐渐晋升至中级软件工程师(高级程序员)、高级软件工程师及架构师等。走这条路,通常可进入电信、银行、保险等相关软件开发公司从事软件设计和开发工作。在信息时代,越来越多的公司重视信息化,信息化落实起来离不开软件开发,而软件开发中Java当属挑大梁者。如果选择这个方向,程序员要脚踏实地,一步一个脚印地练好Java的基本功。对于初(中)级程序员来说首先应掌握Java的基本语法(如类与对象、构造方法、引用传递、内部类、异常、包、Java常用类库、Java IO及Java类集等)。如果读者定位高级程序员以上的目标,那么目标的实现主要依赖3点:一是前期扎实的Java基础,二是后期对软件开发的持续性热爱,三是程序员个人的领悟。

(二)成为技术类管理人员

此类管理人员通常包括产品研发经理、技术经理、项目经理及技术总监等。如果选择管理方向,首先要有一定的“基层”经验,即你至少要有几年的Java开发经验,否则,即使偶然因素让你“擢升”至管理层,你也会因为“外行指导内行”而饱受质疑。所以如果想成为管理人员,那么成功的第一步就是至少成为一名中级以上的Java程序员,前面所言的Java基础也是需要掌握的。想成为技术类管理人员,还要深谙Java设计模式及软件工程的思想,从而能把控软件开发的全局。一个好的技术类管理人员,不仅要自身具有很强的技术管理能力,同时也要有很强的技术体系建设和团队管理的能力,对自己所处行业的技术发展趋势和管理现状具有准确的判断。统筹全局、集各个层次的技术人员之力,高质量地完成软件项目,是成为技术类管理人员的挑战。

(三)在其他领域成就大业

Java软件开发的发展前景好,应用范围也广,具备Java基础的工程师,还可以尝试着在其他领域成就一番大业。例如Java工程师可以从事JSP网站开发、移动领域应用开发、电子商务开发等。如果从事Web开发,那么在此之前一定要熟练掌握HTML、JavaScript、XML(Extensible Markup Language,可扩展标记语言)。Web开发的核心就是进行数据库的操作,先学习Java服务器页面(Java Server Pages,JSP)技术标准,并可以使用JSP + JDBC(Java Data Base Connectivity,Java数据库连接)或者JSP + ADO(ActiveX Data Objects,动态数据操作对象)完成操作。JSP技术是以Java作为脚本语言的。之后再学习MVC设计模式,它是软件工程中的一种软件架构模式,把软件系统分为3个基本部分:模型(Model)、视图(View)和控制器(Controller)。掌握了MVC设计,读者也就可以轻松地掌握AJAX(Asynchronous JavaScript and XML,异步JavaScript和XML)和Struts技术。AJAX 是在不重新加载整个页面的情况下与服务器交换数据并更新部分网页的手段。Struts 是Apache软件基金会(ASF)赞助的一个开源项目。使用Struts机制可以帮助开发人员减少运用MVC设计模型来开发Web应用的时间。

之后,再学习Hibernate和Spring等轻量级实体层开发方法等。Hibernate是一个开放源码的Java语言下的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可便利地使用对象编程思维来操纵数据库。Spring Framework是一个开源的Java/Java EE全功能栈,其应用程序框架内包含了一些基于反射机制写的包,有了它以后程序员便可以将类的实例化写到一个配置文件里,由相应的Spring包负责实例化。

以上3条与Java相关的职业发展规划之路,都以夯实Java基础为根本。每一条路要走到顶层,都需要重视基础,一步一个脚印,做事要由浅入深,由简入繁,循序渐进。《礼记·中庸》有言:“君子之道,辟如行远必自迩,辟如登高必自卑。”这句话告诉我们,君子行事,就像走远路一样,必定要从近处开始;就像登高山一样,必定要从低处起步。

0.4 Java学习路线图

本书主要面向初、中级水平的读者。就本书而言,Java学习可以大致分为3个阶段。

对于读者来说,Java学习的路线在整体上需遵循:初级阶段➤中级阶段➤高级阶段。应循序渐进地学习,不建议读者一开始就“越级”学习,需知“欲速则不达”。这3个阶段各自内部的知识点没有必然的先后次序,读者可根据自己的实际情况有的放矢地学习。不管处于哪个学习阶段,读者都要重视Java的实战练习。等学习到高级阶段后,还要用一些项目实训来提升自己。

要成为一名Java高手,可能需要经历多年的时间。一些读者担心,自己可能等不到成为高手那一天,就无力进行Java开发了。其实Java相关的开发行业也如陈年美酒,愈陈愈香。想一想,前面提到的Java的核心设计者詹姆斯·戈斯林,发髯皆白,却依然意气风发,时常给比他年轻很多的软件开发精英们讲解Java发展之道,那种指点江山的气势,是何等的豪迈!Java软件开发行业的职业寿命很长,能提供给从业人员更广阔的发展空间。如果想在Java开发相关领域有所建树,多一份持久的坚持是必需的。

从一个Java初学者升级为一个编程高手,从来都没有捷径,其必经的一条成长路线是:编写代码➤犯错(发现问题)➤纠错(解决问题)➤自我提升➤编写代码➤犯错(发现问题)➤纠错(解决问题)➤自我提升……积累了一定的感性认识后,才会有质的突变,提升至新的境界。总之,要想成为一个高水平的Java程序员,一定要多动手练习,多思考。

2000多年前,孔夫子就曾说过:“学而时习之,不亦说乎?”杨伯峻先生在《论语译注》中对这句话有精辟的注解:“学了,然后(按一定的时间)去实习它,不也高兴吗?”对于Java的学习,也应是这样,仅仅懂得一堆Java语法毫无意义,我们必须亲自动手实践它。

最后需要说明的是,想成为Java高手绝对没有什么捷径可走,也绝不是一本书就能成就的,需要学习者不断地自我迭代,在理论上提升自己(如在读完本书后,还可以接着读读《编程之美》《设计模式之禅》《企业应用构架模式》,以及外版书97 Things Every Software Architect Should Know等),并在实战中反复地练习。只有这样,才能让自己操作代码的“动作”收放自如,才能让自己的“招式”炉火纯青。

各位Java爱好者,想在计算为王的大千世界里放马驰骋吗?赶快动手吧!

第Ⅰ篇 基础知识

第 1 章 Java开发环境搭建

第 2 章 Java程序要素概览

第 3 章 Java编程基础——常量、变量与数据类型

第 4 章 编程元素详解——运算符、表达式、语句与流程控制

第 5 章 数组与枚举

第 6 章 类和对象

第 7 章 重复调用的代码块——方法

第1章 Java开发环境搭建

本章首先介绍如何在Windows操作系统中下载与安装JDK,并详细描述其开发环境的配置。然后介绍如何编译和运行初学者的第一个Java程序,再简要介绍在Eclipse环境下如何编写Java程序。

本章要点(已掌握的在方框中打钩)

掌握下载、安装Java开发工具箱方法

掌握开发环境变量的配置方式

学会编写第一个Java程序

学会在Eclipse下编写Java程序

 1.1 Java开发环境

学习Java的第一步,就是搭建Java开发环境(Java Development Kit,JDK)。JDK由一个处于操作系统层之上的开发环境和运行环境组成。JDK除了包括编译(javac)、解释(java)、打包(jar)等工具,还包括开发工具及开发工具的应用程序接口等。当Java程序编译完毕后,如果用户想运行,还需要Java运行环境(Java Runtime Environment,JRE)。

JRE是运行Java程序所必需的环境的集合,包含JVM标准实现及Java核心类库。如果仅仅想运行Java程序,安装JRE就够了,也就是说,JRE是面向Java程序的使用者的。但如果想进一步开发Java程序,那就需要安装JDK,它是面向Java程序员的。Java程序员自然也是Java程序的使用者。

Java程序开发的第一步就是编写Java的源码。而编写源码的工具可以是任何文本编辑器,如Windows操作系统下的记事本、Linux操作系统下的Vim等。这里推荐读者使用对编程语言支持较好的编辑器,如Notepad++、UltraEdit、Editplus等,这类代码编辑器通常有较好的语法高亮等特性,特别适合编写程序代码。

Java源文件编写完毕后,就可以在命令行下,通过javac命令将Java源程序编译成字节码(Byte Code,Java虚拟机执行的一种二进制指令格式文件),然后通过java命令来解释执行编译好的Java类文件(文件扩展名为“.class”)。但如果想正确使用javac和java等命令,用户必须自己搭建Java开发环境。在后续章节,我们将详细介绍相关的配置步骤。

1.2 下载与安装JDK

Oracle公司提供了多种操作系统下的不同版本的JDK。本节主要介绍在Windows操作系统下安装JDK的过程。

1.2.1 下载JDK

在浏览器地址栏中输入Oracle官方网址,打开Oracle官方网站,如下图所示,映入我们眼帘的是Java 13的下载界面。

需要提醒读者的是,对于软件开发而言,过度追求“最新”并非好事。这是因为Java 12和Java 13虽然有很多好的新特性,但它依附的生态还没有建立起来。但是从Java 8到Java 13中间经历了多个版本,在Java 13中增加了很多新的功能,语法结构也有一些变化,所以本书以Java 13版本讲解,这个版本中增加了很多方便用户开发的功能,例如增加了文本块,更新了switch表达式,增加了var等。

单击JDK的【DOWNLOAD】按钮,出现下图所示的下载界面。

如前面章节的介绍, Java技术体系可以分为4个平台:Java SE、Java EE、Java ME和Java Card。后面3个版本都是以Java SE为核心的,所以掌握Java SE十分重要,这也是本书的主要讲解内容。

在Java 的发展过程中,Sun公司的市场推广部门举棋不定,导致其版本编号出现一定的“混乱”,容易让用户产生某种程度的困扰。例如,有的时候读者(特别是初学者)可能会在阅读一些Java书籍时,发现版本为Java 2,如J2EE。有时又发现一些书籍说自己代码的编译平台是Java 6或Java 7,那Java 3 或Java 4 去哪里了?因此这里有必要解释一下。下面简要地介绍一下Java版本号的命名规则。

在Java 1.1之前,其命名方式和传统的方式一样。但当Java 1.1升级到Java 1.2时,Sun公司的Java市场推广部门觉得Java的内涵发生了很大的变化,应给予Java一个“新”的名称——Java 2,而它内部的发行编号仍是Java 1.2。当Java内部发行版本从1.2过渡到1.3和1.4时,Sun公司对外宣称的版本依然是Java 2。Sun公司从来没有发布过Java 3和Java 4。从Java内部发行版本的1.5开始,Sun公司的Java市场推广部门又觉得Java已经变化很大,需要给予一个“更新”的称呼,以便在市场中“博得眼球”,于是将Java 1.5 直接对外宣称为新版本Java 5。依此类推,Java 1.6 对外宣称Java 6,Java 8的内部版本是Java 1.8,如下表所示。

Java内部发行版本

发布时间

Java对外推广版本号

JDK 1.0

1996年1月

Java 1.0

JDK 1.1

1997年2月

Java 1.1

JDK 1.2

1998年12月

Java 2

JDK 1.3

2000年5月

JDK 1.4

2002年2月

JDK 1.5

2004年9月

J2SE 5.0

JDK 1.6

2006年12月

Java SE 6

JDK 1.7

2011年7月

Java SE 7

JDK 1.8

2014年 3月

Java SE 8

JDK 1.9

2017年9月

Java SE 9

JDK 2.0

2018年3月

Java SE 10

JDK 11

2018年9月

Java SE 11.0

JDK 12

2019年3月

Java SE 12.0

JDK 13

2019年9月

Java SE 13.0

为了避免混淆,Oracle公司宣布改变Java版本号的命名方式,自JDK 5.0起,Java以两种方式发布更新:一种是有限更新(Limited Update)方式,其包含新功能和非安全修正;第二种是重要补丁更新(Critical Patch Updates,CPU)方式,只包含安全的重要修正。举例来说, Java SE 8u231 的解释如下图所示。

由于Oracle公司的Java实施的是“许可证(License)”,所以在下载与安装时需要选择“Accept License Agreement(接受许可证协议)”复选框,然后选择与自己的操作系统匹配的JDK版本,如下图所示。

读者朋友可以根据自己的操作系统类型以及位数(32位还是64位),下载所对应的JDK。Java 13的JDK软件包大小通常在100MB以上,下载需要一定的时间。下面介绍JDK在Windows操作系统下的详细安装流程。

1.2.2 安装JDK

在下载过程中,有个小问题需要读者注意:如何识别自己所使用的Windows操作系统的版本号?在Windows 10操作系统下,按【Windows】+【Pause】组合键,或在桌面上右击“此电脑”图标,选择【属性】选项,在弹出的【属性】窗口中(见下图),“系统类型”处即可显示读者所用的操作系统的版本信息。

本书使用的Java 13的版本号是Java SE 13.0.1。编程语言的发展趋势是一直向上升级,但只要大版本“13”不变,后面的小版本号即使有所变化,也都属于Java 13的范畴,基本上不会影响普通用户的学习和工作。

安装环境如下。

开始安装。

下载完成后,就可以安装JDK了。双击“jdk-13.0.1_windows-x64_bin.exe”,弹出安装界面,如下左图所示。

选择安装路径。

单击【下一步】按钮,如下左图所示。选择安装路径,然后单击【下一步】按钮,如下右图所示。

至此,JDK安装完成,如下图所示。

查看JDK的安装目录,如下图所示(C:\Program Files\Java\jdk-13.0.1)。

1.3 Java环境变量的配置

1.3.1 理解环境变量

本书主要以Windows 10操作系统为平台来讲解Java。而在开发Java程序之前,通常需要先在Windows操作系统中配置好有关Java的系统环境变量(Environment Variable)。

在介绍环境变量的含义之前,我们先举一个形象的例子,让读者有一个感性的认识。例如我们喊一句:“张三,你妈妈喊你回家吃饭!”可是“张三”为何人?他在哪里呢?对于我们人类来说,认不认识“张三”都能给出一定的响应:如果认识他,可能就会给他带个话;而不认识他,也可能帮忙吆喝一声“张三,快点回家吧”。

然而对于操作系统来说,假设“张三”代表的是一条命令,它不认识“张三”是谁,也不知道“张三”来自何处,它会“毫无情趣”地表示不认识“张三”—— not recognized as an internal or external command(错误的内部或外部命令),然后拒绝继续服务。

为了让操作系统“认识”张三,我们必须给操作系统有关张三的精确信息,如“XXX省YYY县ZZZ乡QQQ村张三”。但其他的问题又来了,如果“张三”所代表的命令是用户经常用到的,每次使用“张三”,用户都在终端敲入“XXX省YYY县ZZZ乡QQQ村张三”,这是非常烦琐的,有没有简略的办法呢?

聪明的系统设计人员想出了一个简易的策略——环境变量。把“XXX省YYY县ZZZ乡QQQ村”设置为常见的“环境”,当用户在终端仅仅敲入“张三”时,系统自动检测环境变量集合里有没有“张三”这个人,如果在“XXX省YYY县ZZZ乡QQQ村”找到了,就自动替换为一个精确的地址“XXX省YYY县ZZZ乡QQQ村张三”,然后继续为用户服务。如果整个环境变量集合里都没有“张三”,那么再拒绝服务,如下图所示。

操作系统里没有上/下行政级别的概念,但有父/子文件夹的概念,二者有相似之处。对“XXX省YYY县ZZZ乡QQQ村”这条定位“路径”,操作系统可以用“/”来区分不同级别的文件夹,即“XXX省/YYY县/ZZZ乡/QQQ村”,而“张三”就像这个文件夹下的可执行文件。

下面我们给出环境变量的正式定义。

环境变量是指在操作系统指定的运行环境中的一组参数,它包含一个或者多个应用程序使用的信息。环境变量一般是多值的,即一个环境变量可以有多个值,各个值之间以英文状态下的分号“;”(即半角的分号)分隔开来。

对于Windows等操作系统来说,一般有一个系统级的环境变量Path。当用户要求操作系统运行一个应用程序,却没有指定应用程序的完整路径时,操作系统首先会在当前路径下寻找该应用程序,如果找不到,便会到环境变量Path指定的路径下寻找。若找到该应用程序则执行它,否则给出错误提示。用户可以通过设置环境变量来指定自己想要运行的程序所在的位置。

例如编译Java程序需要用到javac命令,其中javac中的最后一个字母“c”就来自英文的“编译器”(Compiler)。而运行Java程序[类(class)文件]则需要java命令来解释执行。事实上,这两个命令都不是Windows操作系统自带的命令,所以用户需要通过设置环境变量(JDK的安装位置)来指定这两个命令的位置。设置完成后,就可以在任意目录下使用这两个命令,而无须每次都输入这两个命令所在的全路径(如C:\Program Files\Java\jdk-13.0.1)。javac和java等命令都放在JDK安装目录的bin目录下。类似于环境变量Path,我们需要掌握JDK中比较重要的3个环境变量,下面一一介绍。

1.3.2 JDK中的3个环境变量

对于环境变量中相关变量的深刻理解极为重要,特别是ClassPath,在日后的Java学习开发过程中你会发现,很多问题的出现都与ClassPath环境变量有关。读者在学习如何配置这些环境变量之前,很有必要深刻理解下面3个环境变量代表的含义。

(1)JAVA_HOME:顾名思义,该变量是“JAVA的家”,指的是安装Java的JDK路径,它告知操作系统在哪里可以找到JDK。

(2)Path:前面已经有所介绍,该变量是告诉操作系统可执行文件的搜索路径,即可以在哪些路径下找到要执行的可执行文件,请注意它仅对可执行文件有效。当运行一个可执行文件时,用户仅需给出其文件名,操作系统首先会在当前目录下搜索该文件,若找到则运行它;若找不到,则根据Path变量所设置的路径,逐条到Path目录中搜索该可执行文件所在的目录(这些目录之间是以分号“;”隔开的)。

(3)ClassPath:该变量用来告诉Java解释器(即java命令)在哪些目录下可找到所需要执行的类文件(即javac编译生成的字节码文件)。

对于初学者来说,Java运行环境的配置比较麻烦,请读者按照以下介绍实施配置。

JAVA_HOME的配置

下面我们详细说明Java的环境变量的配置流程。

在桌面上右击【此电脑】,在弹出的快捷菜单中选择【属性】选项,如下图所示。

在弹出界面的左上方选择【高级系统设置】选项,如下图所示。

这时弹出【系统属性】对话框,然后单击【高级】➤【环境变量】按钮,如下图所示。

在【环境变量】对话框中,单击【系统变量】下的【新建】按钮,显示如下页左图所示。

在【新建系统变量】对话框中设置变量名为“JAVA_HOME”,变量值为“C:\Program Files\Java\jdk-13.0.1”。需要特别注意的是,这个路径的具体值根据读者安装JDK的路径而定,读者把Java安装在哪里,就把对应的安装路径放置于环境变量之内,不可拘泥于本书演示的这个路径值。然后单击【确定】按钮,如下图所示。

注意

假设JDK安装在“C:\Program Files\Java\jdk-13.0.1”,在设置完对应的环境变量JAVA_HOME后,再用到这个变量时,需用两个“%”将其包起来。例如要设置另外一个环境变量的值为“C:\Program Files\Java\jdk-13.0.1\bin”(javac、javadoc及java等命令在该目录下),那么我们可以简单地用“%JAVA_HOME%\bin”代替。

Path的配置

选中【系统变量】中的Path,单击【编辑】按钮,如下图所示。

如右图所示,在弹出的【编辑环境变量】对话框中,单击【新建】按钮,打开文本框,在文本框中添加“%JAVA_HOME%\bin”,然后单击【确定】按钮,返回【系统属性】对话框。这里的“%JAVA_HOME%\bin”就是指代前面设置的“C:\Program Files\Java\jdk-13.0.1”。这样的设定是为了避免每次引用这个路径都输入很长的字符串。如果不怕麻烦,“%JAVA_HOME%\bin”完全可以用全路径“C:\Program Files\Java\jdk-13.0.1\bin”代替。这个路径务必设置正确,因为诸如Java语言的编译命令javac和解释命令java等都在这个路径下,一旦设置失败,这些命令将无法找到。

在【系统属性】对话框中单击【确定】按钮,完成环境变量的设置,如下页图所示。

请注意,要检测环境变量是否配置成功,可以进入命令行模式,在任意目录下输入“javac”命令。如果能输出javac的用法提示,则说明配置成功,如下图所示。

进入命令行模式的方法是,单击Windows 10操作系统的开始菜单,在搜索框中输入“CMD”命令,然后按【Enter】键。

ClassPath的指定

对初学者来说,ClassPath的指定有一定的难度,容易配错。如果说JAVA_HOME指定的是java命令的运行路径的话,那么ClassPath指定的就是java加载类的路径。只有类在ClassPath中时,java命令才能找到它,并解释它。

在Java中,我们可以使用set classpath命令来临时指定Java类的执行路径。下面通过一个例子来了解一下ClassPath的作用。假设这里的HelloWorld.class类位于“C:\example”目录下。

在“E:\”目录下的命令行窗口执行下面的命令。

set classpath=C:\example

之后在“E:\”目录下执行java HelloWorld命令,如下图所示。

从上图所示的输出结果可以发现,虽然在“E:\”目录中并没有HelloWorld.class文件,但是也可以用java HelloWorld命令执行HelloWorld.class文件。之所以会有这种结果,就是因为在“E:\”目录中使用了set classpath命令,它把类的查找路径指向了“C:\example”目录。因此在运行时,Java会自动从ClassPath 中查找这个类文件,而ClassPath中包括了路径“C:\ example”,所以运行成功。

提示

可能有些读者在按照上述方法操作时,发现其并不好用。这里要告诉读者的是,在设置ClassPath时,最好也将ClassPath指向当前目录,即所有的类文件都是从当前文件夹中开始查找“set classpath=.”。在Windows及Linux等操作系统下,一个点“.”代表当前目录,两个点“..”代表上一级目录。读者可以在命令行模式下,分别用“cd .”和“cd ..”感受一下。

但是这样的命令行操作模式实际上又会造成一种局限:这样设置的ClassPath只对当前命令行窗口有效。一旦命令行窗口重新开启或系统重启,原先ClassPath中设置的变量值都会丢失。如果想“一劳永逸”,可以将ClassPath设置为环境变量。

参照JAVA_HOME的配置,在【环境变量】对话框中,单击【系统变量】下的【新建】按钮,新建一个环境变量,变量名为“ClassPath”,变量值为“.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar”,如下图所示。注意不要忽略了前面的“.”,这里的小点“.”代表的是当前路径,既然是路径,自然也需要用分号“;”隔开。JDK的库所在包即tools.jar也要设置进ClassPath中。

提示

在Windows操作系统环境下,一般只要设置好JAVA_HOME就可以正常运行Java程序。默认的ClassPath是当前路径(即一个点 “.”)。有些第三方的开发包需要使用到环境变量ClassPath,因为只有这样才能够使用JDK的各种工具。但是开发人员最好养成一个良好的习惯,设置好ClassPath。此外,需要注意的是,在Windows操作系统下不区分大小写,ClassPath和CLASSPATH是等同的,读者可根据自己的习惯选择合适的大小写。而在Linux/UNIX/macOS操作系统环境下,大小写是完全区分开的。

在按照步骤设置后,如果在Java类(即class)文件所存储的当前路径下,那么用“java类名”方式解释执行用户类文件是没有问题的。但是如果用户更换了路径,现在的“当前路径”并没有包括类文件的所在文件夹,那么java命令就无法找到这个类文件。

这时即使在命令行下给出类文件所在的全路径,Java依然会出错,这会让初学者很困惑。下面具体说明。假设Java文件HelloWorld.java存在于“C:\src\chap01\”路径下,由于JAVA_HOME和Path环境变量正确,用户可以正确编译、运行,使用javac和java命令无误,如下图所示。

但是如果用户切换了路径,例如使用cd命令切换至“C:\src\”,再次用Java运行HelloWorld类文件,就会得到错误信息“错误: 找不到或无法加载主类 HelloWorld”,如下图所示。这是因为Java在ClassPath里找不到HelloWorld.class,因为现在的这个当前路径(也就是那个“.”代表的含义)已经变更为“C:\src\”,而“C:\src\”路径下确实没有HelloWorld.class这个文件。

所以如果想在任意路径下执行用户的类文件,就必须把用户自己编译出的类文件所在路径(这里指的是“C:\src\chap01”)也加入ClassPath中,并用分号“;”与前一个变量隔开,如下图所示。

参照环境变量Path的配置,将环境变量ClassPath添加到Path的最后。其中ClassPath是环境变量,在另外一个地方作为变量使用时,要用两个“%”将该变量前后包起来——%ClassPath%,如下图所示。

需要注意的是,如果用户原来的命令行窗口一直开启着,则需要关闭再重启命令行窗口。这是因为只有重启窗口才能更新环境变量。之后就可以在任意路径下执行用户自己的类文件,如下图所示。

1.4 享受安装成果——开发第一个Java程序

“HelloWorld”基本上是所有编程语言的经典起始程序。在编程史上,它占据着无法撼动的历史地位。将“Hello”和“World”一起使用的程序,最早出现于1972年由贝尔实验室成员布莱恩·科尔尼干(Brian Kernighan)撰写的内部技术文件Introduction to the Language B。这里我们也要向“经典”致敬,就让我们第一个Java小程序也是“HelloWorld”吧,从中感受一下Java语言的基本形式。

范例 1-1 编写HelloWorld.java程序

01     public class HelloWorld
02     {
03           //main是程序的起点,所有程序由此开始运行
04           public static void main(String args[])
05           {
06                  //下面的语句表示屏幕上输出“Hello World!”字符串
07                  System.out.println("Hello World!");
08           }
09
10    }

将上面的程序保存为“HelloWorld.java”文件。行号是为了让程序便于被读者(或程序员)理解而人为添加的,真正的Java源码是不需要这些行号的。在命令行中输入“javac HelloWorld.java”,没有错误后输入“java HelloWorld”。运行结果如下图所示,显示“Hello World!”。

Java程序运行的流程可用下图来说明。所有的Java源码(以“.java”为扩展名)通过Java编译器javac编译成字节码,也就是以“.class”为扩展名的类文件。然后利用命令java将对应的字节码通过Java虚拟机解释为特定操作系统(如Windows、Linux等)能理解的机器码,最终Java程序得以执行。

需要注意的是,此处的java命令在Windows操作系统下不区分大小写,如java 和JavA是等同的。而在诸如Linux/macOS等类UNIX(UNIX-like)操作系统下,由于区分大小写,javac和java等所有命令的字符都必须小写。

对于上面的程序,如果暂时不明白也没有关系,读者只要将程序在任意纯文本编辑器(如Windows操作系统下的记事本、Notepad++等,Linux操作系统下的Vim等,macOS操作系统下的TextMate等)里敲出来,然后按照步骤编译、执行就可以了,如下图所示。

需要说明的是,从Java 11开始Java增加了新的功能,可以直接运行Java源文件,而无须先对其进行编译,如可以直接使用命令java HelloWorld.java 运行程序,迈出脚本编写的一步,如下图所示。

下面让我们来解读一下这个Java小程序,让读者对Java程序有个初步的认知。更为详细的知识点读者可以参考后续相关章节进行学习。

在【范例1-1】中,第01行的public 是一个关键字,用于声明类的权限,表明这是一个公有类,其他任何类都可以直接访问它。class 也是Java的一个关键字,用于类的声明,其后紧跟的就是类名,这里的类名是HelloWorld。

第02和第10行这一对花括号{}标明了类的区域,在这个区域内的所有内容都是类的一部分。

第03和第06行这两行为注释行,可以提高程序的可读性。注释部分不会被执行。这种注释属于单行注释,要求以双斜线“//”开头,后面的部分均为注释。

第04行是一个main()方法,它是整个Java程序的入口,所有的程序都是从public static void main(String args[ ] )开始运行的,该行的代码格式是固定的。String args[ ] 不能漏掉,如果漏掉,在一些编辑器中(如Eclipse),该类不能被识别执行。String为参数类型,表示字符串类型,args是参数(arguments)的缩写。public 和static都是Java的关键字,它们一起表明main()是公有的静态方法。void也是Java的关键字,表明该方法没有返回值。对于这些关键字,读者可以暂时不用深究,在后面的章节中会详细讲解main()方法的各个组成部分。

第05和第08行是main()方法的开始和结束标志,它们声明了该方法的区域,在{}之内的语句都属于main()方法。

第07行System.out.println是Java内部的一条输出语句。引号内部的内容“Hello World”会在控制台中输出。

1.5 Eclipse的使用

1.5.1 Eclipse概述

Eclipse 是一个开放源码的、基于 Java 的可扩展开发平台,它为程序员提供了卓越的程序开发环境。

Eclipse的安装非常简单,下载Eclipse安装包(Eclipse Installer),双击安装包图标,选择“Eclipse IDE for Java Developers”(Java程序员专用Eclipse集成开发环境),如下图所示。

启动Eclipse后,它首先让用户选择一个工作空间(Workspace),如下图所示。“工作空间”实际上是一个存放Eclipse建立的项目的目录,包括项目源码、图片等,以及用户有关Eclipse个性化的一些设置(如用于语法高亮显示的颜色、字体大小及日志等)。一般来说,不同的Java项目,如果设置不同,需要使用不同的工作空间来彼此区分。如果用户想备份自己的软件项目,只要复制该目录即可。

在【Workspace】文本框中输入指定的路径,如“C:\Users\zhang\eclipse-workspace”(这个路径可以根据读者自己的喜好重新设定),然后单击【Launch】按钮,如下图所示。

然后就可成功启动Eclipse。Eclipse安装包会自动在桌面创建一个快捷方式,下次启动直接用鼠标双击快捷方式即可。下面我们就介绍一下,如何利用Eclipse完成前面的“HelloWorld”程序,从而让读者对Eclipse的使用有个初步的感性认识。

1.5.2 创建Java项目

在Eclipse中编写应用程序时,需要先创建一个项目。在Eclipse中有多种项目(如CVS项目、Java项目及Maven项目等),其中Java项目是用于管理和编写Java程序的,这类项目是我们目前需要关注的。其他项目属于较为高级的应用,读者在有一定的Java编程基础后,可参阅相关资料来学习它们的应用。创建Java项目的具体步骤如下。

选择【File】(文件)➤【New】(新建)➤【Java Project】(Java项目)选项,打开【New Java Project】(新建Java项目)对话框,如下图所示。

在弹出的【New Java Project】对话框的【Project Name】(工程名称)文本框中输入工程名称“HelloWorld”,并设置其他信息,如下图所示。

单击【Finish】(完成)按钮,完成Java项目的创建,在【Package Explorer】(包资源管理器)窗口中便会出现一个名称为“HelloWorld”的Java项目,如下图所示。

1.5.3 创建Java类文件

通过前面创建Java项目的操作,在Eclipse的工作空间中已经有一个Java项目了。构建Java应用程序的下一个操作,就是要创建HelloWorld类。创建Java类的具体步骤如下。

单击工具栏中的【New Class】(新建类)按钮(如下页右图)或者在菜单栏中选择【File】➤【New】➤【Class】选项(如下页左图),启动新建Java类向导。

在【Source folder】(源文件夹)文本框中输入Java项目源程序的文件夹位置。通常系统向导会自动填写,如无特殊情况,不需要修改。

在【Package】文本框中输入该Java类文件准备使用的包名,系统默认为空,这样会使用Java项目的默认包。

在【Name】(名称)文本框中输入新建类的名称,如“HelloWorld”。

勾选【public static void main ( String [ ] args )】复选框,向导在创建类文件时,会自动为该类添加main()方法,使该类成为可以运行的主类。

单击【Finish】按钮,完成Java类的创建,并写上一行代码System.out.println(“Hello World”),如下图所示。

1.5.4 运行Java程序

前面所创建的HelloWorld类是包含main()主方法的,它是一个可以运行的主类。具体运行方法如下。

单击工具栏中的三角小按钮,在弹出的【Save and Launch】(保存并启动)对话框中单击【OK】按钮,保存并启动应用程序。如果勾选【Always save resources before launching】(在启动前始终保存资源)复选框,那么每次运行程序前将会自动保存文件内容,从而就会跳过下图的对话框。

单击【OK】按钮后,程序的运行结果便可在控制台中显示出来,如下图所示。

1.6 在AndroidStudio中运行Java程序

Java是很多程序员学习Android应用开发的首选语言。虽然现在Android应用开发支持各种语言,但是Java语言有各种优势,其地位很难动摇。主要原因是Android系统本身就是用Java语言编写的,Android系统所依赖的Android SDK中包含许多标准的 Java 类库。Java有跨平台优势,不同类型手机的硬件千差万别,但Java只需要编写一套代码就可以适用于各种手机,而C/C++需要针对各个机型进行编译。而且Java经过多年的发展,拥有大量熟悉Java的人员,他们使用Java开发Android应用可以很快地上手操作,学习成本更低。

有时候在Android开发的过程中需要写一些Java小程序测试一下方法是否正确。但是创建一个Android工程又比较麻烦,而且运行Android项目还需要开启虚拟机,运行一次程序的时间也比较长,所以如果能在AndroidStudio中直接运行纯Java程序就会非常有用。这里介绍一种使用AndroidStudio运行纯Java程序的方法。

打开AndroidStudio,选择【File】➤【New Module】选项打开【Create New Project】对话框,如下图所示。

在【Create New Project】对话框上选择【Java Library】,然后再单击【Next】按钮。

然后在【Library name】文本框中填写创建类的名字,再单击【Finish】按钮,如下图所示。

新建的Java Library如下图所示。

在MyClass类中写入main()方法,把需要的代码写到main()方法中,代码如下。

01      package com.example.testjava;
02      public class MyClass {
03              public static void main(String[] args){
04                      System.out.println("Hello World!");
05              }
06      }

然后选择MyClass文件,右击鼠标,在弹出的快捷键菜单中选择【Run 'MyClass.main()'】运行程序,如下图所示。

运行程序的结果如下图所示。

1.7 高手点拨

1. 如何在命令行模式下正确运行Java类文件?

使用javac编译java源码生成对应的“.class”文件(如【范例1-1】所示的HelloWorld.class),然后用java来运行这个类文件,初学者很容易犯错,很有可能得到如下错误信息。

Error: Could not find or load main class HelloWorld.class

产生这种错误的原因通常有两个。

(1)Java环境变量JAVA_HOME及ClassPath设置不正确。在设置环境变量时,在前一个环境变量前一定要用分号“;”,以此区分不同的环境变量。同时要把当前目录以“.”的形式放进环境变量中。这里的一个小点“.”代表的就是类文件所在的当前目录。

(2)有可能初学者在命令行模式下会按如下方式来运行这个类文件。

java  HelloWorld.class

而正确的方式如下。

java HelloWorld

Java 13版本也可以直接使用下面的命令。

java HelloWorld.java

也就是说,java操作的对象虽然是类文件,但是无须类文件的扩展名“.class”。加上这个扩展名就属于画蛇添足,反而让编译器不能识别。

2. 正确保存Java的文件名。

需要初学者注意的是,虽然一个“.java”文件可以定义多个类,但只能有一个公有(public)类。而且对于一个包括public类名的Java源程序,在保存时,源程序的名称必须要和public类名称保持完全一致,例如下面所示的一个类。

public class HelloWorld
{   }

这个public类的名称是HelloWorld,那么这个类所在的源文件必须保存为HelloWorld.java。由于Java语言是区分大小写的(这和Windows操作系统不区分大小写是不同的),因此保存的Java文件名(除了扩展名“.java”)必须和public类的名称一致,包括大小写也必须一模一样。

1.8 实战练习

编写一个Java程序,运行后在控制台中输出“不抛弃,不放弃,Java,I am coming!”。

相关图书

Effective Java中文版(原书第3版)
Effective Java中文版(原书第3版)
Java核心技术速学版(第3版)
Java核心技术速学版(第3版)
Java编程动手学
Java编程动手学
Java研发自测入门与进阶
Java研发自测入门与进阶
Java开发坑点解析:从根因分析到最佳实践
Java开发坑点解析:从根因分析到最佳实践
Java EE企业级应用开发实战(Spring Boot+Vue+Element)
Java EE企业级应用开发实战(Spring Boot+Vue+Element)

相关文章

相关课程