学习领域1:Java语言概述 〖1〗 Java语言程序设计(第二版) 〖1〗 学习领域1Java语言概述 〖1〗 〖1〗 任务11安装Java开发环境 本部分介绍Java语言的发展历程、技术特点和Java体系结构等,使读者对Java语言有一个基本的认识。随后配置Java开发环境,使初学者能够以较高的效率开发Java应用程序。 111任务内容 Java开发环境的搭建:安装JDK 17和集成开发环境Eclipse,开发执行第一个Hello World程序。执行过程如下。 (1)JDK的安装与配置。 (2)Java开发环境的配置。 (3)IDE集成开发环境Eclipse的安装与配置。 (4)开发执行Java Application应用程序和Java Applet小应用程序。 112相关知识 知识点一:Java语言简介 1991年,Sun公司的James Gosling等人为了解决消费类电子产品的微处理器计算问题,开发出一种名为 “Oak”(中文译为“橡树”)的与平台无关的语言,它就是Java语言的前身。它用于控制嵌入在有线电视交换盒、PDA(Personal Digital Assistant,个人数字助理)、家用电器等的微处理器中。 1993年交互式电视和 PDA 市场用量开始滑坡,而 Internet 正处于发展时期,因此Sun 公司将目标市场转向 Internet 应用程序。 1994年Sun公司将Oak语言更名为Java(Java译为“爪哇”,是印度尼西亚一个盛产咖啡的岛屿),并于1995年正式推出它的第一个版本。Internet的迅猛发展与WWW(万维网)应用的快速增长,为Java的发展带来了契机。Java语言优秀的跨平台特性使之非常适合于Internet编程,最初用Java语言编写的Hot Java浏览器和应用于Web页面的Applet程序,使Java语言成为Internet上最受欢迎的开发语言。Sun公司采取了“开放式”的合作政策,采用了颁发使用许可证的方式来允许各家公司把Java虚拟机(JVM)嵌入自己的操作系统或应用软件中,这吸引了大批公司加入到Sun联盟,如IBM、HP、Netscape、Novell、Oracle、Apple等公司;而且开发平台的源代码完全开放,这使得开发人员很容易只使用一种Java语言来实现网络各平台之间的开发、编程和应用,这也是Java语言得以迅猛发展的一个主要原因。现在全球有近70%的公司使用Java语言开发自己的计算机软件系统。 1995年,Sun公司发布了Java的第一个版本Alpha 10a2版本,开发出Hot Java浏览器。1996年,Sun公司发布了Java的第一个开发包JDK v10。1997年,Sun公司发布了Java开发包JDK v11。1998年,Sun公司发布了Java开发包JDK v12(称为Java 2)。 1999年,Sun公司重新组织了Java平台的集成方法,并将企业级应用平台作为公司今后发展的方向。现在的Java开发平台的编程构架一共有三种:J2SE、J2EE、J2ME。 J2SE (Java 2 Platform, Standard Edition ) ,即Java 2平台标准版,包含构成Java语言核心的类。它是用于工作站、PC的开发平台,也是三个编程构架中最基本的一个构架,J2EE和J2ME就是在J2SE的基础上发展、转化而来的。 J2EE (Java 2 Platform, Enterprise Edition ),即Java 2平台企业版。J2EE应用于可扩展的、基于分布式计算的企业级开发平台,如Intranet(企业内部网),有业界大量的其他软件技术融入J2EE构架中(如微软的XML技术),因此它具有更高的可扩展性、灵活性和集成性。 J2ME (Java 2 Platform,Micro Edition ),即Java 2平台微型版。J2ME用于嵌入式开发,为消费类电子产品软件开发服务,如手机系统或手机游戏软件的开发。 三种版本使用的类库也不尽相同,本书内容的大部分类都来自J2SE构架。 知识点二:Java语言的特点 1简单性与分布式 Java作为一种高级编程语言,在语法规则上和C++类似,C++程序员会比较容易地掌握Java编程技术。Java摒弃了C++容易引起错误的内容,如指针操作和内存管理,使程序设计变得简单、高效。 Java是面向网络的编程语言,它提供了基于网络协议(如TCP/IP)的类库。使用这些类,Java应用程序可以很容易地访问网络上的资源。Java应用程序可通过一个特定的URL对象打开并访问网络资源,就像访问本地文件系统那样简单。 2纯面向对象 面向对象编程技术具有很多优点,比如通过对象的封装,减少了对数据非法操作的风险,使数据更加安全;通过类的继承,实现了代码的重用,提高了编程效率等。Java语言的编程主要集中在类、接口的描述和对象引用方面。面向对象编程技术适合开发大型的、复杂的应用程序,且程序代码易于理解和维护,是编程发展的一个趋势。 3健壮性与安全性 Java语言在编译和运行时具有健壮性,可以消除程序错误带来的影响。Java语言提供了较完备的异常处理机制,在编译和运行程序时,系统对代码进行逐级检查,指出可能产生错误的地方,要求必须对可能存在错误的代码进行必要的处理,以消除因产生错误而造成系统崩溃的情况。它提供自动垃圾收集功能来进行内存管理,防止出现程序员在管理内存时容易产生的错误,这些措施都保证了Java系统运行的可靠性。 作为网络编程语言,安全是至关重要的。一方面,在语言功能上,由于Java不支持指针,消除了指针操作带来的安全隐患;另一方面,Java具有完备的安全结构和策略,代码在编译和运行过程中被逐级检查,可以防止恶意程序和病毒的攻击,如编译器会查找出代码错误,编译之后生成字节码,通过字节码校验器,病毒代码将无所遁形,因此也有人称Java语言为“永远不会感染病毒的语言”,在加载类的时候,还会通过类加载器进行校验。 4平台独立与可移植性 互联网是由各种各样的计算机平台构成的,如果要保证应用程序在网络中任何计算机上都能正常运行,必须使程序具有平台无关性,即软件本身不受计算机硬件系统和操作系统的限制。Java是一种“与平台无关”的编程语言,Java的源文件是与平台无关的纯文本,而Java源文件通过编译后生成的类文件(即字节码文件)通过Java虚拟机(JVM)可以在不同的平台上运行,与具体机器指令无关。Java的基本数据类型在设计上不依赖于具体硬件,为程序的移植提供了方便。 5解释执行 Java是一种先编译后解释执行的编程语言,Java源程序经过编译后生成被称作字节码(Byte Code)的二进制文件,JVM 的解释器解释执行字节码文件。解释器在执行字节码文件时,能对代码进行安全检查,以保证没有被修改的代码才能执行,提高了系统的安全性。另外,JVM由Sun公司特别制作并在网上实时更新,它的运行效率远高于一般的解释性语言的解释器。 6多线程与动态性 多线程机制使程序代码能够并行执行,充分发挥了CPU的运行效率。程序设计者可以用不同的线程完成不同的子功能,极大地扩展了Java语言的功能。支持多线程机制是现今网络开发语言的基本特性之一。 Java在设计上力求适合不断发展的环境。在类库中可以自由地加入新的方法和实例而不会影响用户程序的执行。Java通过接口来支持多重继承,使之比严格的类继承具有更灵活的方式且易于扩展。Java的类库是开放的,所有的程序员可以根据需要自行定义类库。 知识点三:Java平台特性 1了解Java的跨平台特性 什么是平台呢?简单的理解是计算机软件系统与计算机硬件系统的结合体。比如IBM PC Windows机、Apple公司的Mac OS等。我们知道,不同种类的计算机有不同的机器语言(内码),为一种平台编写的代码不能在另一种平台上运行,这是因为它们的内码不同。 编程语言分为三类:机器语言、汇编语言、高级语言。 Java语言是一种“先编译后解释”的高级语言,它的地位等同于C、C++或Visual Basic等语言。从功能上来看,Java也可以实现C、C++或Visual Basic等语言的大部分功能,如控制台(Console)程序和GUI(Graphics User Interface,图形用户界面)程序,只不过侧重点有所不同。Java语言是基于Web开发的一种高级语言,它的“强项”在网络上! 下面我们介绍一下Java的编译和运行过程,如图11所示。 图11 Java编译与运行过程 Java语言通过编译器在本地将源程序(扩展名为java)文件编译成字节码文件(扩展名为class),可以通过复制或通过网络传送到目的平台,然后通过目的平台的解释器(也可能是浏览器的解释器)来解释执行。 那么Java又是如何完成跨平台的呢?如图12所示,Java在运行过程的中间环节引入了解释器来帮助它完成跨平台。 图12 Java语言的运行过程 下面介绍一个非常重要的概念——Java虚拟机(Java Virtual Machine,JVM)。 JVM是在计算机内部模拟运行的假想的计算机。它可以是硬件或软件(通常为软件)。它有自己独立的指令集系统(相当于计算机的CPU、内存和寄存器等设备)。JVM负责将Java字节码程序翻译成机器码,然后由计算机执行。 JVM的主要功能为:加载 class 文件,管理内存,执行垃圾收集。 在计算机执行Java程序时,需要JVM和核心类库的支持。Java采用的方法是:在操作系统和硬件平台上模拟一种抽象化的计算机系统运行时环境(Java Runtime Environment,JRE),而JRE包含了JVM和运行程序所需系统核心类库。JVM和JRE是随着JDK(Java Development Kit,Java 开发工具包)的安装而建立起来的。 对Java语言而言,它的源文件和字节码文件(中间码文件)都是与平台无关的,它们可以通过网络传输到任何一个网络平台中并可以被识别。然后通过目标平台本地的JVM解释执行。但要注意:JVM是与平台相关的。因为字节码是通过网络传输到目标计算机平台上再通过JVM运行的,而不同种类的计算机有不同的内码,从这里就可以推断出,每一个特定平台上应该有一个特定的JVM,即JVM是与平台相关的。 2Java程序的运行时环境 前面介绍了Java虚拟机(JVM)的概念,JVM的核心是解释器。而程序运行时需要的是JRE,可以简单地把JRE理解成工作在操作系统之上的一个小型操作系统,它包含了运行在其上的JVM及本地平台的核心类库,如图13所示。 下面详细描述JRE中各部件的作用。 (1) 类加载器(Class Loader):用来加载Class文件的部件,同时针对跨网络的类,进行安全性检查。 (2) 字节码校验器(Byte Code Verifier):基于代码规范,对语法语义、对象类型转换和权限安全性访问进行检查。 (3) 解释器(Interpreter):JVM的核心部件,把字节码指令映射到本地平台的库和指令上,使之得以执行。 图13 Java运行时环境 (4) JIT代码生成器(Just In Time):即时代码生成器(即时代码编译器)是另一种解释执行字节码的方法。通常的解释器是逐行解释和运行,而编译器是对代码做全体编译后再连接执行,因此解释型语言的执行效率一般都低于编译型语言。而为了提高运行效率,Java提供了JIT运行方式,它可以一次性地解释完所有代码,再去运行机器码,而且曾经解释过的代码会进入缓存,如果下次再调用这部分代码,就从缓存中取出,这样就极大地提高了Java的运行效率。因为这种解释运行的方式类似于编译器,因此也称其为“JIT即时编译器”。JIT就类似于引擎对于一辆赛车的意义,是JRE的核心部件。 (5) API类库:实现标准Java平台API的代码。 (6) 硬件本地平台接口:提供对底层系统平台资源库的调用接口。 3垃圾收集器 许多计算机语言都有在程序运行时动态分配存储空间的功能,当这部分内存空间不再使用的时候,程序应停止分配内存空间并回收它们。但是回收内存空间却不是件容易的事情,C和C++语言通常需要程序员自行编写代码回收动态内存空间,这增加了程序员的负担,还会因为代码不健壮造成系统问题。 Java语言提供了一个自动进行内存管理的工具,就是垃圾收集器(Garbage Collector)。它是一个系统级的线程,专用于对内存进行跟踪和回收。但因为垃圾收集器是一个优先级比较低的后台线程(Daemon Thread),所以它只在系统有空闲的时候才会回收垃圾内存,而且也无法判断垃圾收集器何时回收内存,以及要运行多长时间,这一切都是自动完成的。这使得程序在运行时会出现不连贯的现象,在一定程度上降低了代码的运行效率,但这个代价还是值得付出的。 知识点四:JDK目录结构 1什么是JDK JDK(Java Development Kit)即Java 开发工具包,是有助于程序员开发Java 程序的工具包,其中包括类库、编译器、调试器、Java 运行时环境(JRE)。 Sun公司为各种主流平台(如Windows、Solaris、Macintosh等)制作了JDK,可以从网址http://Javasuncom//products/下载JDK。如下载的文件为j2sdk1_6_0betawindowsi586exe,表示此JDK为Java 2标准版,版本号为16(内部版本号为60),beta表示测试版,适用于Windows系统的计算机。 2JDK的目录结构 下载并安装完JDK后,假设安装的目录为:C:\\Program Files\\Java\\j2sdk160。在 \\Java\\j2sdk160目录下有以下文件及子目录。 根目录包括版权、许可和Readme文件,还有构成Java核心API的所有类文件的归档文件srcjar。 bin目录是JDK开发工具的可执行文件,包括编译器、解释器、调试器等。 demo目录中有丰富的演示程序源代码。 include目录支持Java本地机接口(JNI)和Java虚拟机调试程序接口的C语言头文件。 JRE(Java Runtime Environment),即Java运行时环境,包含JVM、运行时的类包和Java链接启动器,但是不包含编译器和调试器。jre目录包含的部分子目录及文件如下。 lib/jawjar:提供了Netscape的JavaScript和Security类。 lib/charsetsjar:字符转换类。 lib/rtjar:Java基本类库(JFC)。 lib/ext/:包含扩展的jar文件。 bin/keytool:密码认证和管理工具。 另外,\\jre\\bin目录下,还包括Java Web Start(JWS)的运行程序Javawsexe。 lib目录包含开发工具使用类的归档文件。其中有: toolsjar:包含支持JDK的工具和实用程序的非核心类。 dtjar:是Swing组件类BeanInfo文件的DesignTime归档。 sample目录中有一些JNLP(Java网络装载协议)应用的样例程序。JNLP能使远程客户访问和运行那些位于本地机器的应用程序。JNLP应用程序的优点是它可以在网络上实现自安装和自更新。 知识点五:Java程序开发 Java的基础应用中包含两种类型的应用:一种是Java Application,称为Java应用程序;另一种是Java Applet,称为Java小应用程序。 Java Application以main()方法作为程序入口,由Java解释器解释执行,用以实现控制台或GUI方面的应用。 Java Applet没有main()方法,但是有init()和paint()等方法,由浏览器解释执行,主要用于在网页上显示动画等功能。对此本书只做简单介绍,因为Applet已基本不再被使用。 1Java Application应用程序开发 【例11】编写一个在屏幕上显示“Hello World !”字符界面的应用程序。 public class HelloApp{ // 定义公共类HelloApp public static void main(String\[ \] args){// 应用程序入口即main()方法 Systemoutprintln("Hello World !"); // 输出Hello World ! } } 例11是最简单的Java应用程序,它给出了Java应用程序的基本框架。 注意以下几点内容。 (1) 类是构成Java程序的主体,class是类的说明符号,类中包含了实现具体操作的方法。 (2) 使用“//”声明的部分是Java的注释,它有助于程序的阅读,在编译时不会被编译。 (3) 每个应用程序中必须包含主方法main(),主方法是程序的入口,读者可先记住声明格式,不要改变关键字顺序。 (4) Systemoutprintln()方法起到输出作用,直接输出括号内的内容。 (5) 读者在编写以上程序时要注意字母大小写,Java语言中严格区分大小写。 2Java Applet小应用程序开发 Applet应用程序是嵌入在HTML(Hypertext Markup Language,超文本标记语言)文件中的Java程序。它可以连同Web页面一起被下载到客户的浏览器中,并由实现了JVM的浏览器运行。编写Applet程序时,需要编写出相应的HTML文件,并在文件中加上调用Applet程序的标记。 【例12】编写在浏览器中显示“Hello World !”的Java Applet程序。 import javaappletApplet; // 打开Applet类所在的包applet import javaawt.*; // 打开Graphics类所在的包awt public class SimpleApplet extends Applet{// 创建继承Applet类的SimpleApplet public void paint(Graphics g) { // 调用Applet类的paint()方法 gdrawString("Hello World !",50,50); // 绘制"Hello World !" } } 用于编写HTML文件的工具有很多,复杂的HTML文件可以用目前较为流行的可视化制作工具(如FrontPage、Dreamweaver)创建,简单的文件可以用文本编辑工具直接编写。本例使用的HTML文件的代码如下: The Simple Applet 在上面的代码中,“”是调用SimpleAppletclass的标记。可以用Web浏览器或JDK提供的appletviewer运行Applet应用程序。 知识点六:Java语法规则 字符是组成Java程序的基本单位,Java语言源程序使用Unicode字符集。Unicode采用16位二进制数表示1个字符,可以表示65 535个字符。标准ASCII码采用8位二进制数表示1个字符,共有128个字符。如果要表示像汉字这样由双字节组成的字符,采用ASCII码是无法实现的。ASCII码对应Unicode的前128个字符。因此,采用Unicode能够比采用ASCII码表示更多的字符,这为在不同的语言环境下使用Java奠定了基础。 1Java程序注释 注释是用来对程序中的代码进行说明、帮助程序员理解程序代码的,还有利于对程序代码进行调试和修改。在系统对源代码编译时,编译器将忽略注释部分的内容。Java语言有3种注释方式: (1) 以// 分隔符开始的注释,用来注释一行文字。 (2) 以/* … */ 为分隔符的注释,可以将一行或多行文字说明作为注释内容。 (3) 以/** … */ 为分隔符的注释, 用于生成程序文档中的注释内容。 下面以实例说明以上三种注释的用法。 【例13】注释方法举例。 /**************** *程序名称:HelloWorldjava * *作者:Sunlina * *日期:2014/08/06 * ****************/ public class HelloWorld{ String strMsg="Hello,World!" ; // 定义变量strMsg /** This method is used to display greeting message!*/ void init() {// 定义init()方法 Systemoutprintln(strMsg) ; // 输出字符串内容 } public static void main(String\[ \] args) {// 主方法即程序入口 new HelloWorld()init() ; // 引用init()方法 } } 一般情况下,如果阅读源程序代码,用方法(1)和方法(2)给代码加注释。如果程序经过编译之后,程序员得不到源程序代码,要了解程序中类、方法或变量等的相关信息,可以通过生成程序注释文档的方法,使程序员通过阅读注释文档,了解到类内部方法和变量的相关信息。 JDK提供的Javadoc工具用于生成程序的注释文档。将例13程序生成注释文档须执行: Javadoc private HelloWorldjava 该命令执行结束后,生成名为indexhtml的文件。在浏览器中阅读该文档,可以看到程序中方法和变量的说明信息。参数“private”表示生成的文档中,将包括所有类的成员。如果需要更详细的注释信息,可以在要说明的成员前面用/**…*/加注释,如程序中关于init()方法的说明,注释的信息将出现在生成的文档中。 2Java的标识符 我们已经接触到简单的Java程序,了解到Java程序的基本组成。Java程序是由类和接口组成的,类和接口中包含方法和数据成员。编写程序时,需要为类、接口、方法和数据成员命名,这些名字称为标识符。 标识符可以由多种字符组成,可以包含字母、数字、下划线、美元符($),但首字符不能是数字,不能包括操作符号(如+、-、/、*等)和空格等。例如,HelloWorld、setMaxValue、UPDATE_FLAG都是合法的标识符;而123、UPDATEFLAG、ab*cd、begin flag等都是非法的标识符。 Java是区分大小写的编程语言,字符组成相同但大小写不同视为不同的标识符,如strName和StrName标识不同的名称。 3Java的关键字 标识符用于为类、方法或变量命名。按照标识符的组成规则,程序员可以使用任何合法的标识符,但Java语言本身保留了一些特殊的标识符——关键字,它不允许在程序中为程序员定义的类、方法或变量命名。关键字有着特定的语法含义,一般用小写字母表示。以下列出了Java语言中使用的关键字。 abstractdefaultifprivatethis booleandoimplementsprotectedthrow break double import public throws byte else instanceof return transient case extends int short try catch final interface static void char finally long strictfp volatile class float native super while const for new switch continue goto package synchronized 4Java的分隔符 在编写程序代码时,为了标识Java程序各组成元素的起始和结束,通常要用到分隔符。Java语言有两种分隔符:空白符和普通分隔符。 空白符:包括空格、回车、换行和制表符等符号,用来作为程序中各个基本成分间的分隔符,各基本成分之间可以有一个或多个空白符。系统在编译程序时,忽略空白符。 普通分隔符:也用来作为程序中各个基本成分间的分隔符,但在程序中有确定的含义,不能忽略。Java语言有以下普通分隔符。 ● { } 大括号,用来定义复合语句(语句块)、方法体、类体及数组的初始化。 ● ;分号,语句结束标志。 ● ,逗号,分隔方法的参数和变量说明等。 ● :冒号,说明语句标号。 ● \[ \] 中括号,用来定义数组或引用数组中的元素。 ● () 圆括号,用来定义表达式中运算的先后顺序;或在方法中,将形参或实参括起来。 ● 用于分隔包,或者用于分隔对象和对象引用的成员方法或变量。 113任务实施 本任务为安装和配置JDK开发环境与Eclipse集成环境。 1任务分析 (1) 掌握安装JDK 18的方法。 (2) 掌握Java开发环境的配置。 (3) 掌握IDE集成开发环境Eclipse的安装与配置。 (4) 掌握如何在Eclipse中建立工程。 (5) 掌握如何在Eclipse中编写和执行Java Application程序。 (6) 掌握如何在Eclipse中编写和执行Java Applet程序。 (7) HTML文档中嵌入Java Applet程序。 2安装JDK环境 (1)从Oracle公司https://wwworaclecom/technetwork/java/javaee/downloads/indexhtml网站下载Windows版的JDK8,双击下载的exe文件,如jdk8u141windowsx64exe,进入安装向导界面,如图14所示。 图14安装向导界面 (2) 单击“下一步”按钮进入“自定义安装”界面,如图15所示。默认安装到“C:\\Program Files\\Java\\jdk180_141\\”目录下,可以通过“更改”按钮对安装路径进行自定义,这里我们使用默认安装路径。 图15自定义安装 (3) 选择安装JDK所有组件后,单击“下一步”按钮进入安装进度界面,如图16所示。 图16安装进度 (4) 接下来询问是否安装JRE(Java Runtime Environment,Java运行环境) ,如图17所示。因为JDK中已经包含Java的开发环境和运行环境。若仅对已有的Java程序进行运行,而不需要进行Java程序的开发,那么可以安装一个独立的JRE,单击“下一步”按钮,如图18所示。 图17JRE安装询问 图18正在安装JRE (5) JDK安装完成后,进入图19所示界面,下面可以配置Java开发环境了。 图19JDK安装完成 3设置Java开发环境 为了方便使用JDK中的Java工具,需要进行环境变量的配置。环境变量就是操作系统运行环境中的一些参数。Java要使用到操作系统的参数path,它记录了很多命令所属的路径,只要将Java开发中需要的命令所属的路径配置到path参数值中即可。具体操作步骤如下。 (1) 右击桌面上“我的电脑”图标,打开“系统属性”对话框,选择“高级”标签,单击“环境变量”按钮,如图110所示。 图110环境变量设置 (2) 选择名称为Path的变量,单击“编辑”按钮,如图111所示。出现Path变量的编辑对话框。不必删除原有的值,只要将光标移动到第二个文本框的起始处即可,如图112所示。 图111环境变量中选择“Path”进行编辑 图112编辑系统变量“Path” (3) 复制图113中地址栏的目录路径,将复制内容粘贴到图112最左边光标所在位置,并用分号与原有的值进行分隔,如图114所示,然后单击“确定”按钮完成。 图113复制路径 图114添加路径至系统变量“Path”中 (4)在环境变量窗口里的“Administrator的用户变量”中点击“新建”按钮,如图115所示,增加JAVA_HOME变量。 图115新建环境变量“JAVA_HOME” (5)按照图116所示,在用户变量JAVA_HOME中,设置变量值为 C:\Program Files\Java\jdk180_141,单击“确定”按钮完成。 图116编辑系统变量“JAVA_HOME” (6) 最后验证配置正确性。从“开始”菜单中打开“运行”对话框,输入cmd命令,如图117所示,单击“确定”按钮后进入DOS命令提示符界面,输入Javac命令,如果出现图118所示界面,说明环境配置成功,可以进行Java代码开发了。 图117运行cmd命令 图118运行Javac命令 4安装Eclipse环境 这里介绍IBM公司开发的IDE开发环境Eclipse,它是一个开放源代码的、基于Java的可扩展开发平台。 (1) Eclipse的下载 进入Eclipse的官方网站http://www.eclipse.org/downloads,如图119所示,可以自行下载合适的Eclipse安装版本。本教材提供Eclipse oxygen 470的资源安装包,直接安装即可。 图119Eclipse的官方网站 (2) Eclipseoxygen 470软件的解压 如图1-20所示,将“eclipsejeeoxygenRwin32x86_64”软件压缩包放置于E盘进行解压,生成目录“E:\Eclipse”。 图120解压位置对话框 (3) 运行eclipseexe文件 进入目录“E:\Eclipse”,在图121中双击运行eclipseexe文件,弹出图122和图123所示的界面。如果无法启动,则说明JDK没有安装好,或者PATH环境变量没有设置正确。 图121运行eclipseexe文件 图122eclipse的启动界面 图123Workspace Launcher对话框 在图123的文本框中输入工作区文件夹,本例为“E:\Eclipse_java\lizi”。应该先在E盘建立该目录,再单击右侧的Browse按钮来选择。不要手写目录路径,很可能会写错的。单击“Launch”按钮,启动程序,弹出图124所示的窗口。 图124eclipse的欢迎界面 在图125中单击“新建工程项目”选项,弹出125所示窗口。注意,右上角“Java”透视图表示在此操作界面可以建立和运行Java程序。 图125eclipse的操作界面 5Java Application源程序建立及运行 (1) 建立工程。单击File→New Project选项,如图126所示,选择Java Project,弹出图127所示窗口。之后再次进入可以直接选择已经建立的Java Project项目。 图126建立一个工程的操作界面 在图127的Project name文本框中输入工程名,例如给出的工程名为“c1”,然后单击Finish按钮,弹出如图128所示窗口。 图127New Java Project窗口 在图128中显示建好的“c1”工程,在此操作界面可以编写Java程序。 图128建好的“c1”工程 (2) 建立Java Application源程序。单击File→New→Class选项, 如图129所示。 图129建好的“c1”工程中建立Java源程序 在打开的图130所示窗口的Name文本框中输入Java源程序名,扩展名不用写,默认为“java”。例如,给出的Java源程序名为“C1_1”,在复选框中勾选public static void main后单击Finish按钮,弹出如图131所示窗口。 图130New Java Class窗口 图131中是一个空的Java Application应用程序框架,可以在此编写程序。本例建立的C1_1java源程序如图132所示。 图131空的Java Application应用程序框架 图132编写“C1_1java”程序 (3) 编译运行Java Application源程序。在图132所示的菜单中单击Run→Run As→1 Java Application选项,如图133所示,弹出如图134所示窗口,单击OK按钮,结果如图135所示。如果编译Java Application源程序没有错误,则在Console控制台选项中可以看到运行结果。如果编译Java Application源程序有错误,则在Console控制台选项中可以看到错误信息,需修改源程序再编译运行。本例编写的“C1_1java”程序的运行结果显示在Console控制台选项中。 图133编译运行“C1_1java”程序 图134Save and Launch窗口 图135“C1_1java”程序的运行结果 6Java Applet源程序建立及运行 (1) 建立一个工程。建立工程参照图126和图127的操作。本例中给出的工程名为“c2”,然后单击Finish按钮,弹出如图136所示窗口。 图136建好的“c2”工程 (2)建立Java Applet源程序。在图136中显示建好的“c2”工程,单击File→New→Class选项,如图137所示,弹出如图138所示窗口。 图137在建好的“c2”工程中建立Java源程序 在图138中的Name文本框里输入Java源程序名,扩展名不用写,默认为“java”。 图138在c2工程中建立C1_2 源程序 本例中给出的Java源程序名为“C1_2”,在复选框中勾选Inherited abstract methods(继承的抽象方法),单击Browse按钮,弹出如图139所示窗口。在Choose a type文本框中输入“javaapple”,然后单击OK按钮,弹出如图140所示窗口。从中单击Finish按钮,弹出如图141所示窗口。 图139Superclass Selection窗口 图140c2工程的New Java Class窗口 图141中是一个空的Java Applet程序框架,可在此编写程序。本例建立的C1_2java源程序如图142所示。 图141空的Java Applet程序框架 图142编写“C1_2java”程序 (3) 编译运行Java Applet源程序。在图142的菜单中单击Run→Run As选项,本例编写的“C1_2java”程序的运行结果如图143左上角所示,这是小应用程序浏览器——appletviewer,用于测试和运行Java Applet程序。如果编译Java Applet源程序有错误,需修改源程序后再编译运行。 图143运行“C1_2java”程序的结果 7在HTML文档中嵌入Java Applet程序 (1) 建立一个工程。建立工程与图136的操作过程一样。本例中给出的工程名为“c3”,然后单击Finish按钮,弹出如图144所示窗口。 (2) 建立Java Applet源程序。在图144中显示建好的“c3”工程,建立Java Applet源程序与图142的操作过程一样。本例建立的C1_3java源程序如图145所示。 (3) 建立HTML文档。在图145中单击File→New→File选项,如图146所示,弹出如图147所示窗口。 在图147中的File name文本框里输入文档名,本例名为“c1_3html”,单击Finish按钮,弹出如图148所示的窗口。在其中输入文档内容,结果如图149所示。 HTML文档中使用标签的codebase代码属性来直接调用相关节点的Java Applet。codebase为字节码文件所在位置;code为字节码文件名;width为宽度;height为高度。宽度和高度是浏览器中显示的Java Applet的窗口宽度与高度(以像素为单位)。 (4) 查看c3工程中C1_3java、C1_3class、c1_3html所在位置。在图149的菜单中单击Window→Show View→Navigator选项,如图151所示,弹出如图152所示窗口。 图144建好的“c3”工程 图145编写“C1_3java”程序 图146建立“c1_3html”文档 图147New File窗口 图148空HTML文档框架 图149“c1_3html”文档 图150选择“Navigator”导航选项 从图151左边区域可以看到c3工程中C1_3java、C1_3class、c1_3html所在位置。 图151显示三个文件所在位置 (5) 解释HTML文档。如图152所示,在c3文件夹下用浏览器解释c1_3html,解释结果如图153所示。 图152找到c1_3html文件 图153c1_3html解释结果 114技能提高 下面介绍在JDK环境中运行Java程序。 1运行Java Application源程序过程 步骤一:使用文本编辑器编辑此源文件,存盘文件名为MyApplicationjava。 步骤二:配置path和JAVA_HOME环境变量。 步骤三:编译文件,启动控制台,进入源文件所在目录。在DOS提示符下输入命令: Javac MyApplicationjava,将编译成字节码文件MyApplicationclass。 步骤四:解释执行,在DOS提示符下输入命令:Java MyAppliction,会得到程序要求显示的所有信息,如图154所示。 图154编译与解释执行结果(一) 2运行Java Applet源程序过程 步骤一:使用文本编辑器编辑此源文件,存盘文件名为MyAppletjava。 步骤二:配置path和JAVA_HOME环境变量。 步骤三:编译文件,启动控制台,进入源文件所在目录。在DOS提示符下输入命令:Javac MyAppletjava,将编译成字节码文件MyAppletclass。 步骤四:解释运行Applet。运行Applet有两种方法,可以在浏览器中解释运行,或利用JDK提供的AppletViewerexe工具运行。 (1) 在浏览器中解释执行Applet程序的方法如下。 因为Applet是在浏览器中以HTML文件的一部分的形式来运行的,因此需要一个包含它的HTML文件,格式为: 用文本编辑器编辑它,将文件保存到字节码文件所在的目录,可任意命名,假设为HelloApplethtml,然后运行HelloApplethtml,就会在浏览器中看到要显示的所有信息,如图155所示。 图155编译与解释执行结果(二) (2) 使用AppletViewerexe工具运行Applet程序的方法如下。 AppletViewerexe工具位于JDK安装目录下的bin目录里,运行格式为: DOS提示符> appletviewer HelloApplethtml 执行命令后在AppletViewer工具窗口中显示出结果,如图156所示。因为JDK类库时常更新,所以不能保证旧版本浏览器中的JVM能准确地解释最新类库制作的Java Applet程序。因为AppletViewer工具随Sun公司官方提供的JDK版本更新,因此能保证支持运行Applet程序。 图156编译与解释执行结果(三) 任务12Java基础程序设计 Java语言的基本元素是数字和字符。要学会用字符和数字编写程序,必须掌握Java的语法规则。本节主要介绍Java语言的基本数据类型、运算符、表达式和程序的流程控制。 121任务内容 编写一个字符界面的Java Application程序,接收用户输入的10个整数,比较并输出其中的最大值和最小值。操作步骤如下。 (1) 声明变量与常量。 (2) 利用输入流与缓冲区读取对象,接收从键盘输入的10个整型数据。 (3) 利用选择结构进行数据比较。 (4) 利用循环结构获取最大值与最小值。 122相关知识 知识点一:数据类型 Java语言有两种类型的数据:基本类型(primitive)和引用类型(reference)。 基本类型包括8种:布尔型(boolean)、字节型(byte)、字符型(char)、短整型(short)、整型(integer)、长整型(long)、浮点型(float)和双精度型(double)。 引用类型包括3种:类(class)、接口(interface)和数组(array)。 不同类型数据的取值及取值范围不同,在内存中所占用的空间也不同。表11给出了基本数据类型的数据取值范围和所占用的内存空间。 字符型数据采用Unicode编码,占用两个字节的内存。同ASCII码字符集相比,Java的字符型数据能够表示更多字符。表中“\\u…”表示采用Unicode编码方式。 表11基本数据类型 数据类型 所占空间(字节) 取值范围 布尔型(boolean) 1 false逻辑假或true逻辑真 字节型(byte) 1 -128~+127 字符型(char) 2 '\\u0000'~'\\uFFFF' 短整型(short) 2 -215~215-1,即-32 768~+32 767 整型(int) 4 -231~231-1,即-2 147 483 648~+2 147 483 647 长整型(long) 8 -263~263-1 浮点型(float) 4 -34E-38~34E+38 双精度型(double) 8 -17E-308~17E+308 知识点二:常量和变量 1常量 在程序中以数据值本身字面意义出现的数据称为直接量(literal)或常量,每个直接量必须属于一种数据类型。例如255是一个int类型的数值。直接量的作用是为变量赋值或参与表达式运算。 (1) 布尔常量 boolean类型的常量只有true和false两个值,代表“真”和“假”。书写时不加单引号('')或者双引号("")。 (2) 整型常量 整型常量是不含有小数的整数值,可以用来为整型变量赋值。可以采用十进制数、八进制数和十六进制数来表示整型常量。 八进制整型常量用以0开头的数值表示,如025表示十进制的21;十六进制的整型常量用以0x开头的数值表示,如0x25表示十进制的37。对于长整型的常量,表示时要在相应的数值后加符号L或l,如127L。 (3) 浮点型常量 浮点型常量是含有小数部分的数值常量。依据占用内存空间的多少,分为单精度和双精度浮点数常量。浮点数可以用十进制数形式表示,如123456;也可以用科学记数法形式表示,如123e4和123e4,其中e或E之前必须有数字,而e或E之后必须为整数。float浮点数数值后加F或f,double浮点数可以加D或d,也可以不加后缀。 (4) 字符常量 字符常量是由一对单引号括起来的单个字符,可以是Unicode字符集中的任意一个字符,如'H'、'9'、'$'等;也可以是转义字符,或者直接写出的字符编码。 转义字符是一些具有特殊含义和功能的字符,如执行回车、换行等操作。Java中所有转义字符都用反斜线(\\)开头,后面跟一个表示特定含义的字符。表12列出了常用的转义字符及其代表的含义。 表12转 义 字 符 转义字符 Unicode编码 字符功能 \\b \\u0008 退格 \\r \\u000d 回车 \\n \\u000a 换行 \\t \\u0009 水平制表符 \\f \\u000c 进纸 \\' \\u0027 单引号 \〖WTBKB〗" \\u0022 双引号 2变量 在程序运行过程中,数值可变的量称为变量。变量用于存放运算的中间结果和保存数据。在程序中变量用合法的标识符命名;在内存中变量对应一定大小的内存空间。变量依据其所表示的数据对象而具有不同的类型。不同类型的变量占用的内存空间各不相同。 (1) 变量的声明 使用变量时,必须指出变量的名称和类型,以便为变量分配足够的内存空间。给变量命名必须遵从标识符的命名规则。但给变量命名,除了按照标识符的命名规则外,还要考虑一些特殊的约定。比如,变量名首字符要小写,变量名前加上表示变量类型的前缀等。定义变量采用以下格式: \[访问修饰符\]\[存储修饰符\]<数据类型><变量名> ; 其中方括号表示可选项,即访问修饰符和存储修饰符是可选的;尖括号表示必选项,即数据类型和变量名是必选的。修饰符将在后续内容中加以详细介绍。变量名要符合前面提到的标识符命名规则。数据类型中,对基本数据类型要用基本数据类型的代表符号;对引用数据类型要用类的名称。下面举例说明变量的声明方法。 【例14】定义变量训练。 boolean bFlag;// 声明布尔型变量bFlag char cKeyin;// 声明字符型变量cKeyin byte btRead;// 声明字节型变量btRead int iCount;// 声明整型变量iCount float fSum;// 声明浮点型变量fSum double dAmount;// 声明双精度浮点型变量dAmount 上面的例子中变量名都加了前缀,这样便于在阅读程序时很容易知道变量的类型。变量名前缀一般取数据类型标识的首字符,作为特例byte类型用bt。 (2) 变量初始化 给变量赋初值,即为变量初始化。Java采用“=”符号为变量赋初值。例如bFlag=true;iCount=100;fSum=255f等。对基本类型的变量,也可在声明的同时进行初始化,如char cKeyin='h';double dAmount=998等。 【例15】变量初始化和常量显示的方法举例。 public class PrimitiveData{ public static void main(String\[ \] args){ boolean bFlag=true; byte btVar=125; char cVar='J'; int iVar=1096; float fVar=12356f; double dVar=12356; Systemoutprintln("bFlag初始值= "+bFlag); Systemoutprintln("btVar初始值= "+btVar); Systemoutprintln("cVar初始值= "+cVar); Systemoutprintln("iVar初始值= "+iVar); Systemoutprintln("fVar初始值= "+fVar); Systemoutprintln("dVar初始值= "+dVar); Systemoutprintln("***常量显示***"); Systemoutprintln("短整型常量:"+067); Systemoutprintln("长整型常量:"+0x3a4FL); Systemoutprintln("八进制字符常量:"+'\\141'); Systemoutprintln("十六进制字符常量:"+'\\u0061'); Systemoutprintln("浮点型常量:"+314F); Systemoutprintln("双精度常量:"+314); Systemoutprintln("***非数字常量显示***"); Systemoutprintln("非数字常量:"+0d/0d); Systemoutprintln("***常变量赋初值***"); final float f2=9f; Systemoutprintln("常变量:"+f2); } } 【运行结果】 bFlag初始值= true btVar初始值= 125 cVar初始值= J iVar初始值= 1096 fVar初始值= 12356 dVar初始值= 12356 ***常量显示*** 短整型常量:55 长整型常量:14927 八进制字符常量:a 十六进制字符常量:a 浮点型常量:314 双精度常量:314 ***非数字常量显示*** 非数字常量:NaN ***常变量赋初值*** 常变量:90 【代码说明】 给变量赋值时,应当保证“=”号右边的直接量的类型同左边变量的数据类型一致,否则会产生错误。例如,bFlag=123;iCount=12356f等语句都是错误的。 (3) 变量的作用域 变量可分为全局变量和局部变量,而变量的分类取决于作用域。全局变量指具有类块作用域的类成员变量;局部变量指具有方法块作用域的变量。局部变量必须初始化或者赋值,否则不能使用;而全局变量是有默认初始值的,默认初始值的情况见表13。 表13类成员变量的默认值 类成员变量的数据类型 默认值 布尔类型 (boolean) false 整型(integer) 0 浮点型(float) 00 字符型(character) '\\u0000' 关于类成员变量及其作用域的概念,会在后面“面向对象编程”的学习领域中详述,这里先举个简单的例子说明类成员变量的默认值的意义。 【例16】变量的作用域。 public class Var { static int a;// 类的成员变量,是全局变量,作用域在类Var的花括号之间 public static void main(String\[\] args) { int a=10;// 局部变量,作用域在main()方法花括号之间 Systemoutprintln("a="+a);// 输出a的值 } } 【运行结果】 a=10 【代码说明】 当作用域重合时,局部变量覆盖全局变量,结果为10。 如果第5行中的a不设初始值会怎样?编译时会有错误提示“variable a might not have been initialized”(变量没有初始化)。 如果去掉第5行的代码又会输出什么?输出a=0,因为这是输出类成员变量,而类成员变量有默认值。 知识点三:数据类型转换 各种数据类型可以混合运算。运算中,不同类型的数据要先转化为指定的一种数据类型,然后再进行运算。转换的方式分为两种:自然转换和强制转换。 1自然转换 在一个表达式中,如果存在不同的数据类型,可以按照字节数少的类型能够自动转换成字节数多的类型规律运算,自然转换规则由低到高如图157所示,运算规律如表14所示。 低高 byte,short,charintlongfloatdouble 图157自然转换规则 表14自然转换规律 操作数1的数据类型 操作数2的数据类型 自然转换后的数据类型 byte或short int int byte、short或int long long byte、short、int或long float float byte、short、int、long或float double double char int int 精度不同的两种类型的数据混合运算时,低精度数据自动转换为相应的高精度数据类型。 如果操作数为浮点型,那么只要其中一个为double类型,结果就是double类型; 如果两个操作数都为float型,或者一个是float类型而另一个是整型,结果就是float类型; 如果两个操作数为泛整型,只要其中一个是long类型,结果就是long类型; 低于int型的数据(如byte,short,char)之间混合运算时,自然转换为int型数据类型。 【例17】数据类型的自然转换。 public class TransferType { public static void main(String\[\] args) { byte b=1; short s=2; char ch='a'; long l1=3L; float f1=123F; double d1=456D; int i=b+s+ch; long l2=il1; float f2=b+f1; double d2=d1/s; Systemoutprintln("i="+i); Systemoutprintln("l2="+l2); Systemoutprintln("f2="+f2); Systemoutprintln("d2="+d2); } } 【运行结果】 i=100 l2=97 f2=223 d2=228 2强制转换 如果高精度数据向低精度数据转换,就需要使用强制类型转换运算符“(数据类型)”。但强制转换会造成精度丢失,最好不要使用。示例: int a; a=(int)364d;// 强制转换后,a值为3 知识点四:运算符和表达式 在数学运算中,我们用运算符号代表各种运算操作,程序中要进行运算同样需要运算符。Java语言的运算符按功能可分为赋值运算符、算术运算符、关系运算符、逻辑运算符、位运算符、条件运算符等。由运算符将变量、常量、方法等连接起来,便构成表达式。 1赋值运算符 “=”号是最简单的赋值运算符,其左边是变量,右边是表达式。表达式的运算结果应和左边的变量类型一致,或者能够转换为左边变量的类型。例如: int i;// i为整型变量 float x;// 定义浮点型变量 i=128;// 128为整型值,语句正确 i=256f; // 256f为浮点数,浮点数赋给整型变量,存储格式不同,语句不正确 x=129;// 129为整型数值,赋给x后,先转换成浮点数1290,再赋给x 从上面的例子中可以看出,整型数值可以赋给浮点型变量,反过来是不允许的。赋值时,应遵循以下规则:byte→short→int→long→float→double (→表示可赋给)。 赋值运算符“=”还可以同其他运算符结合,实现运算和赋值双重功能。组合方式为: <变量><其他运算符> =<表达式> 这种赋值的含义为:将变量与表达式进行其他运算符指定的运算,再将运算结果赋给变量。例如执行: int i=5; i+=21; 相当于执行:i=i+21,结果为5+21=26。 2算术运算符 算术运算符分单目运算符和双目运算符。单目运算符只有一个参与运算的操作数,双目运算符有两个参与运算的操作数。表15列出了算术运算符类型、用途和相关说明。 表15算术运算符 运算符 用途 举例 说明 ++,-- 自动递增,自动递减 ++i,j-- i先加1,再参与运算;j参与运算再减1 +,- 取正、负号 i=-25 将25取负号后赋给i * 乘 i=15*2 将15乘以2后赋给i / 除 fVar=250f/5 用5去除250,结果赋给fVar % 取余 j=5%3 将5除3取余,结果为2 +,- 加、减 x=fVar-89 将fVar减去89,结果赋给x 表中“++”和“--”为单目运算符,运算符可以放在变量之前,也可以放在变量之后,如++i,i++。虽然两种运算都是自动加1,但用在表达式中,两者是有区别的。前一种操作是在i参与其他运算前,先加1;后一种操作是在i参与运算后,再加1。 【例18】递增运算符应用举例。 public class Let{ public static void main(String\[ \] args){ int iCount=99 , iSum=0 , iAver=0 ; iSum+=iCount++ ;// iSum=0+99;iCount=99+1 Systemoutprintln("iCount="+iCount) ;// iCount=100 Systemoutprintln("iSum="+iSum) ;// iSum=99 iAver+=++iCount ;// iCount=100+1;iAver=0+101 Systemoutprintln("iAver="+iAver) ; // iAver=101 } } 在程序的注释中给出了运算的结果。在设计程序时,应当正确地使用递增或递减运算符。 3关系运算符 关系运算符用于对两个表达式进行比较,返回布尔型的结果true或false。一般与条件运算符共同构成判断表达式,用作分支结构或循环结构的控制条件。表16列出了关系运算符及其用途和相关说明。 表16关系运算符 运算符 用途 举例 说明 > 表达式1>表达式2 i>100 i大于100,返回true,否则,返回false < 表达式1<表达式2 i<100 i小于100,返回true,否则,返回false >= 表达式1>=表达式2 i>=128 i大于等于128,返回true,否则,返回false <= 表达式1<=表达式2 i<=10 i小于等于10,返回true,否则,返回false == 表达式1==表达式2 i==81 i等于81,返回true,否则,返回false != 表达式1!=表达式2 i!=9 i不等于9,返回true,否则,返回false 【例19】关系运算符应用举例。 public class Compare{ public static void main(String\[ \] args){ int iLeftExp=89 , iRightExp=298 ; boolean bResult ;// 定义存放比较结果的变量 bResult=iLeftExpiRightExp is "+bResult) ; bResult=iLeftExp<=iRightExp ; Systemoutprintln("iLeftExp<=iRightExp is "+bResult) ; bResult=iLeftExp!=iRightExp ; Systemoutprintln("iLeftExp!=iRightExp is "+bResult) ; } } 【运行结果】 iLeftExp>iRightExp is false iLeftExp<=iRightExp is true iLeftExp!=iRightExp is true 4逻辑运算符 逻辑运算符用于连接关系表达式,对关系表达式的值进行逻辑运算。运算符为&&、‖和!。&& 运算符对应AND运算;‖运算符对应OR运算;! 运算符对应NOT运算。表17列出了逻辑运算符及其使用方法。Java中的!、&&和‖运算符采用了电工学中的“短路”方式进行运算,即先求出逻辑运算符左表达式的值,如果其值能够推算出整体表达式的值,就不再运算右侧表达式,这样加快了程序的执行效率,但是也需要注意其中变量值的变化情况。 表17逻辑运算符 运算符 用途 举例 说明 && 逻辑与运算 (9>6)&&(100<125) 左右表达式均为true,结果返回true ‖ 逻辑或运算 (9>6)‖(100>125) 左表达式为true,结果为true ! 取反运算 !(255>125) 比较表达式为true,取反后结果返回false 【例110】观测“短路”运算符的效果。 public class Test{ public static void main(String args\[\]){ int a=2,b=1; Systemoutprintln(""+(a>b||++b>=a)); Systemoutprintln(b); } } 【运行结果】 true 1 【代码说明】 因为逻辑表达式中a>b的值为true,因此整体的表达式就为true,右侧的++b>=a表达式不再参与运算,所以b的值仍为1。 5条件运算符 条件运算符(?:)是唯一的三元运算符,形式为: 表达式1?表达式2:表达式3 表达式1是关系或布尔表达式,返回值为布尔值,如果表达式1的值为true,整体表达式的值为表达式2的值;如果表达式1的值为false,则整体表达式的值为表达式3的值。示例: int a=1800; int salary=a>1600 ? 2000 : 1900;// a>1600结果为true,结果salary值为2000 6表达式 由变量、常量、关键字和运算符进行组合,构成表达式。表达式用来执行程序中要求的计算操作,并返回计算的结果。Java中允许使用类型匹配的简单表达式构造复合表达式,表达式返回值的数据类型取决于表达式中使用的元素类型;表达式的运算顺序由运算符的优先级决定,同样也可通过使用圆括号指定运算顺序。 (1) 运算符的优先级 运算符优先级是指同一表达式中多个运算符被执行的次序。同数学中的运算相类似,不同运算符运算的优先顺序是不一样的。比如,在同一表达式中,如果同时有加、减和乘、除运算,优先计算乘、除,再计算加、减。表18列出了Java运算符的优先级顺序。 表18运算符优先级 优先级 运算符 1  \[ \] () 操作数++ 操作数-- 2 ++操作数 --操作数 ! ~ - 3 new (type) 4 * / % 5 + - 6 << >> >>> 7 < > <= >= instanceof 8 = = != 9 & 10 ^ 11 | 12 && 13 ‖ 14 ? : 15 = += -= 16 *= /= %= 17 &= ^= |= 18 <<= >>= >>>= (2) 运算符运算顺序的规则 由多种运算符连接的变量、常量、成员和表达式构成复合表达式,如表达式: fVar=fA+fB*fA-fB+iVar++ ;// 表达式(1) 在复合表达式中,先进行哪种运算符的计算,应当按照一定的规则。一般情况下,如果运算符的优先级相同,则按照运算符的优先级顺序进行计算,如乘和除运算优先级相同,加和减运算优先级相同。要改变运算顺序,可以用括号将要优先计算的表达式括起来,如表达式: fVar=(fA+fB)*(fA-fB)+iV++ ;// 表达式(2) 表达式(1)和表达式(2)的结果是不同的。 在有赋值、算术、比较、逻辑等运算符组成的复合表达式中,运算规律一般为:算术运算→比较运算→逻辑运算→赋值运算。这是可以理解的,因为计算出结果才能进行比较,比较后才能得到逻辑结果,有了逻辑结果才能进行逻辑运算,赋值时将计算结果赋给变量。 知识点五:流程控制 Java程序是由若干条语句组成的,语句本身是由Java的关键字、表达式等构成。每条语句以分号“;”结束,多条语句组合在一起形成复合语句或语句块,复合语句用大括号{}括起来。 一般情况下,计算机按照语句的先后顺序逐条执行语句。在某些情况下,需要有选择地或者重复地执行某条或某些语句时,则使用程序的流程控制语句。 流程控制结构可以分为:顺序结构、选择(分支)结构和循环结构。 1选择语句 分支语句有if语句和switch…case语句两种。 (1) 简单的if语句 if语句用于进行条件判断,根据判断的结果,选择执行相应的语句或语句块。简单的if语句只有一种选择,执行某语句或不执行某语句。其语法格式为: if(表达式) 语句块 括号中的表达式是一个逻辑表达式,当表达式结果为逻辑“真”时,执行语句块;否则,执行if语句后面的语句。 【例111】将三个整型数中最大数显示出来。 public class DisplayMax{ public static void main(String\[ \] args){ int iA=3,iB=9,iC=5; if(iB=70&&score<80){ Systemoutprintln("你的成绩为中等!"); } if(score>=80&&score<90){ Systemoutprintln("你的成绩为良好!"); } if(score>=90&&score<=100){ Systemoutprintln("你的成绩为优秀!"); } } else{ Systemoutprintln("你的成绩不及格!"); } } } 【运行结果】 输入命令格式:DOS控制台>javaTestIf89 结果显示为:你的成绩为良好! (4) switch语句 使用if语句,能够满足各种条件判断。但在某些情况下,使用if语句不一定很方便。如一个表达式可能有很多取值,要根据不同的取值,决定执行相应的语句。用if语句时,需要较多的if语句进行嵌套,会使程序可读性差,此时可使用switch语句,即多分支选择语句。 switch语句的语法格式为: switch(表达式){ case常量表达式1 : 语句块1 break; case常量表达式2 : 语句块2 break; … case常量表达式m: 语句块m break; default : 语句块m+1 } 语句中switch、case、default是关键字,表达式的类型应为byte、short和int类型,语法中的default子句可以省略。执行switch语句时,先计算表达式,将表达式的值与各个常量表达式的值进行比较,若与某个常量值相等,就执行该常量后面的语句;若都不相等,就执行default后面的语句。若没有default子句,则直接跳出switch语句。 switch语句和if语句分别适用于不同的情况,if语句用于根据一定范围内的值或者条件进行判断;而switch语句用于根据单个整数值(不包括长整型)进行判断,每个case语句中常量表达式的值应是唯一的,不能有相同的常量值。 在switch语句中,使用break语句能跳过其后的判断语句,否则,程序会执行后面case语句中的程序段,而不进行判断,直到再遇到break语句。 【例114】设计简单的计算器,根据输入的运算符号,将两个整数进行相应的计算。 import javaio*; public class Calculation{ public static void main(String\[ \] args)throws Exception{ int iA=255,iB=289; char cOp; Systemoutprintln("Please input opterator:"); cOp=(char)Systeminread(); // read()返回整型数,须强制转换为char switch (cOp) { // cOp为字符型,能够转换成整型且不丢失信息 case '+': Systemoutprintln("iA+iB="+(iA+iB)); break; case '-': Systemoutprintln("iA-iB="+(iA-iB)); break; case '*': Systemoutprintln("iA*iB="+(iA*iB)); break; case '/': Systemoutprintln("iA/iB="+(iA/iB)); break; default: Systemoutprintln("Unknown operator!"); } } } 【运行结果】 Please input operator: + iA+iB=544 【代码说明】 switch语句中的表达式是字符型,这是允许的,因为字符型表达式可以转换为整型表达式而不丢失信息。如果表达式是长整型、浮点型或双精度型,必须进行强制类型转换,使之变成整型表达式,并能够计算出确定的值。 2循环语句 循环语句用于反复执行一段代码,直到满足某种条件为止。Java语言有三种循环语句:while、do…while和for循环语句。 当不知道一个循环要重复执行多少次,可以选择while循环(当型循环)或者do…while循环(直到型循环);如果要执行已知次数的循环,可以使用for循环。但不管怎样,一个完整的循环结构应该包含四个组成部分。 ① 初始化部分(initialization):用于设置循环的初始条件,如设置计数器的初始值。 ② 判断部分(estimation):是一个关系或布尔表达式,用于判断循环是否可以继续运行的条件。 ③ 迭代部分(iteration):修改循环初始条件,用于控制循环的次数,如使计数器的值自增或自减。 ④ 循环体部分(body):循环中反复执行的代码。 (1) while循环语句 while循环又称为“当型循环”,意指当某条件成立时循环执行。while语句的语法格式为: while(条件表达式){ 语句块 } while语句首先计算条件表达式的值,若表达式值为true,则执行语句块,再对表达式进行判断,直到表达式的值为false时,停止执行语句块。while语句中的语句块也叫循环体,循环体中应当有改变表达式值的语句,否则,会造成程序无限循环的情况。 【例115】求整数X的N次幂,并显示出结果。 public class X_N{ public static void main(String\[ \] args){ int iX=2 , iN=7, iXN=1; int i=0 ; // 循环变量 while(iContinue!"); continue;// 修改i值,并判断i<=9 } Systemoutprintln(i+"*"+i+"="+i*i+" ");// i为偶数,计算平方值 }// 循环结束 Systemoutprintln("Finished,bye!");// 循环结束的第1条语句 } } 【运行结果】 2*2=4 i=3->Continue! 4*4=16 i=5->Continue! i=6->Continue! i=7->Continue! 8*8=64 i=9->Continue! Finished,bye! 【代码说明】 continue语句和break语句不同,continue跳过循环体余下部分语句后,重新转到条件判断语句,在该程序中转到for语句,先修改循环变量i的值,然后判断表达式i<=9的值,如果值为真,继续循环;否则,退出循环。 123任务实施 1任务分析 (1) 声明变量、数组和字符串,后续内容会详细介绍,读者不妨先记住代码编写格式。 (2) 利用输入流与缓冲区读取对象,从键盘输入10个整型数据,后续内容会详细介绍,读者不妨先记住代码编写格式。 (3) 利用选择结构进行数据比较。 (4) 利用循环结构获取最大值与最小值。 2程序实现代码 import javaio*; public class Max { public static void main (String args\[\])throws Exception { String s;// 声明字符串对象 int a\[\]=new int\[10\];// 声明可容纳10个元素的数组 int max=0;// 声明最大值变量 int min=0;// 声明最小值变量 for(int i=0;imax)|(a\[i\]==max)){ max=a\[i\]; } } Systemoutprintln("最大值为:"+max+","+"最小值为:"+min); // 输出结果 } } 【运行结果】 4 6 7 11 9 3 2 16 10 15 最大值为:16,最小值为:2 124技能提高 本节进行嵌套循环训练。 在循环体中的语句可以是任何语句,包括循环语句。如果循环体中还有循环语句,便形成了循环嵌套的情况。下面举例说明循环嵌套的编程方法。 【例120】求0~100之间的素数。 public class PrimeNumber{ public static void main(String\[ \] args){ int\[ \] x=new int\[100\]; // 定义具有100个元素的数组x for(int i=1;i<100;i++) // 循环100次,将1~100赋给x的元素 x\[i\]=i; for(int j=1;j=0;i--)// 将strE按相反的字母顺序显示出来 Systemoutprint(strEcharAt(i)); Systemoutprintln(); } } 【运行结果】 How are you Fine!Thank you! We are all happy! 字符串中,字符的位置索引同字符数组是对应的,第一个字符的索引为0,第二个字符的索引为1,依此类推,最后一个字符的索引为字符串长度减1。 (2) StringBuffer类的常用方法及应用 StringBuffer类用于处理可变字符串,该类除了具有与String类相同的方法外,还有其特殊的方法,见表110。 表110StringBuffer类定义的主要方法 方法名称 功能说明 public int length() 返回缓冲区的字符个数 public int capacity() 返回缓冲区的容量 public synchronized StringBuffer append(type variable) 将variable转换成字符串,然后与当前字符串连接 public synchronized StringBuffer insert(int offset,type variable) 将variable转换成字符串,然后插入到当前字符串 中由offset指定的位置 StringBuffer对象在创建时,系统要为其分配一定容量的空间,以处理可变长度的字符串,创建后的对象可以增加、删除内容,经修改的字符串返回给原对象,这和String对象是不同的。StringBuffer对象中字符串的个数可由其length()方法得到,而系统为每个对象分配的缓冲区容量由其capacity()方法获得。创建StringBuffer对象时,系统分配的缓冲区容量等于对象中字符个数加上16。执行追加、插入字符或字符串时,也将改变以上两个方法的返回值。 【例132】字符串StringBuffer类方法的简单应用。 public class StringBufferDemo{ public static void main(String args\[\]){ StringBuffer buf = new StringBuffer() ;// 声明StringBuffer对象 bufappend("World!!") ;// 添加内容 bufinsert(0,"Hello ") ;// 在第一个内容之前添加内容 Systemoutprintln(buf) ;// 输出修改的结果 bufinsert(buflength(),"LNJD~") ;// 再次添加内容 Systemoutprintln(buf) ;// 输出修改的结果 String str = bufreverse()toString() ;// 将内容反转后变为String类型 Systemoutprintln(str) ;// 将内容输出 } } 【运行结果】 Hello World!! Hello World!! LNJD~ ~DJNL!!dlroW olleH 133任务实施 验证登录信息基本功能实现代码如下。 public class LoginDemo{ public static void main(String args\[\]){ if(argslength!=2){// 判断输入的参数个数是否是2 Systemoutprintln("输入的参数不正确,系统退出!") ; Systemoutprintln("格式:javaLoginDemo 用户名 密码") ; Systemexit(1) ;// 系统退出 } String name = args\[0\] ;// 取出用户名 String password = args\[1\] ;// 取出密码 if(nameequals("sunlina")&&passwordequals("lnjd")){// 验证用户名和密码 Systemoutprintln("欢迎" + name + "光临!") ; }else{ Systemoutprintln("错误的用户名或者密码!") ; } } } 【运行结果】 没有输入参数时,显示以下信息: 输入的参数不正确,系统退出! javaLoginDemo用户名 密码 输入错误的用户名或者密码时,显示以下信息: 错误的用户名或者密码! 输入正确的用户名或者密码时,显示以下信息: 欢迎sunlina光临! 【代码说明】 虽然以上程序可以实现基本功能,但在主方法中代码较多,不利于作为客户端进行操作。最简单的做法是:客户端只要得到最终的判断结果即可,中间的过程可以设置其他的类来封装具体的判断过程。在掌握学习领域2的知识点后,改造上例得到实现代码如下。 class Check{// 完成具体的验证操作 public boolean validate(String name,String password){ if(nameequals("sunlina")&&passwordequals("lnjd")){// 验证用户名和密码 return true ;// 登录信息正确 }else{ return false ;// 登录信息错误 } } } class Operate{// 本类只是调用具体的验证的操作 private String info\[\] ;// 定义一个数组属性,用于接收全部输入参数 public Operate(String info\[\]){ thisinfo = info ;// 通过构造方法取得全部的输入参数 } public String login(){ Check check = new Check() ;// 实例化Check对象,用于检查信息 thisisExit() ;// 判断输入的参数是否正确 String str = null ;// 用于返回信息 String name = thisinfo\[0\] ;// 取出姓名 String password = thisinfo\[1\] ;// 取出密码 if(checkvalidate(name,password)){// 登录验证 str = "欢迎" + name + "光临!" ; }else{ str = "错误的用户名和密码!" ; } return str ;// 返回信息给用户 } public void isExit(){// 判断参数个数,来决定是否退出程序 if(thisinfolength!=2){ Systemoutprintln("输入的参数不正确,系统退出!") ; Systemoutprintln("格式:java LoginDemo 用户名 密码") ; Systemexit(1) ;// 系统退出 } } } public class LoginDemo{ public static void main(String args\[\]){ Operate oper = new Operate(args) ;// 实例化操作类的对象 Systemoutprintln(operlogin()) ;// 取得验证之后的信息 } } 【代码说明】 经过程序改造后,可以发现:主方法代码较少,方便客户使用;Check类的主要功能是验证操作,只需要输入用户名和密码即可完成验证;Operate类的主要功能是封装Check类的操作,并把验证后的信息返回给方法调用处。 134技能提高 下面进行数组排序训练。 1采用冒泡法对数组进行排序 public class ArrayDemo1{ public static void main(String args\[\]){ int score\[\] = {57,89,87,69,90,100,75,90} ;// 使用静态初始化声明数组 for(int i=1;i<局部变量>;\] … 方法体语句; }; (1) 类的成员方法在声明或定义前,除了声明方法的返回值数据类型之外,还需要说明方法的访问属性和存储方式。访问修饰符包括public、protected、private和缺省;存储类型修饰符包括static、final、abstract、native、synchronized。各种成员方法访问修饰符的作用与成员变量相同,参见表21。表24给出了各种成员方法存储修饰符的作用。 (2) 如果类体中一个方法只有声明,没有定义(即没有方法体),则此方法是abstract的,类体和方法体定义前都须加abstract关键字修饰。 表24成员方法的存储修饰关键字的功能 关键字 用途说明 static 声明类方法,表明该方法为所有对象所共有 abstract 声明抽象方法,没有方法体,该方法需要其子类来实现 final 声明最终方法,该方法将不能被子类重写 native 声明本地方法,本地方法用另一种语言如C语言实现 synchronized 声明同步方法,该方法在任一时刻只能由一个线程访问 (3) 访问成员方法的格式:对象成员方法。如果考虑static关键字,那么访问格式可细化为:对象 静态成员方法(或实例成员方法),或者类名静态成员方法。 (4) 方法按返回值可以分为两类:无返回值的方法和有返回值的方法。有返回值方法的返回值类型可以是Java允许的任何数据类型。无返回值的方法用void关键字声明,不能包含return语句;有返回值的方法需在方法名前指出方法的返回值类型,并且包含return语句,return语句后面为返回的结果,结果的数据类型即返回值类型,如实例21所示。 (5) 在声明方法中的参数时,需要说明参数的类型和个数。参数之间用逗号隔开,参数的数据类型可以是Java认可的任何数据类型。参数名称在它的作用范围内是唯一的,即同一个方法中的参数名称不能相同。当然对象也可以作为方法的参数,将在214节技能提高中加以介绍。 知识点六:构造方法 构造方法是一种特殊的方法,用来创建类的实例。声明构造方法时,可以附加访问修饰符,但没有返回值,不能指定返回类型。构造方法名必须和类同名。调用构造方法创建实例时,用new运算符加构造方法名,格式如下: 类名称对象名称 = new 类名称() 如创建Student类的实例: class Student{ public Student(){}// 构造方法 public static void main(String args\[ \]){ Student tom=new Student();// 调用构造方法来创建实例 } } 为实例的属性设置值有两种方式:一种是先创建实例,后调用自己的普通成员方法来完成设置,这称为“赋值”;另一种是使用new运算符调用构造方法,一次性地完成实例的创建和属性值设置,这称为“初始化”。 比较两种方式可以容易地知道构造方法的使用时机和作用:构造方法是专门用于构造实例的特殊成员方法,在创建实例时起作用;而使用普通成员方法为实例属性赋值,是在实例创建后才调用。构造方法可以自行定义,以满足程序的需要。在创建实例并设置属性值时虽然有两种选择,但推荐使用构造方法的形式来创建实例,这会使程序更简洁和易于理解,运行效率也更高。 知识点七:方法重载 在同一个类体中有多个名称相同的方法,但这些方法具有不同的参数列表(或参数的个数不同,或参数的类型不同),这种现象称为方法的重载。实例如下所示。 【例23】定义Sum类。 public class Sum { static int add(int x,int y){ return x+y; } static int add(int x,int y,int z){ return x+y+z; } static float add(float x,float y){ return x+y; } public static void main(String\[\] args) { Systemoutprintln(add(2,3)); Systemoutprintln(add(2,3,4)); Systemoutprintln(add(21f,32f)); } } 方法重载是一种静态多态,有时也称为“编译时绑定”。编译器习惯上将重载的这些方法确认为不同的方法,因此它们可以存在于同一作用域内。调用时,根据不同的方法调用格式自动判断、定位到相应的方法定义地址。使用方法重载,会使程序的功能更清晰、易理解,并使得调用形式更简单。 构造方法也是根据需要自行定义的,具有不同参数列表的构造方法也可以构成重载的关系。一个类如果没有定义构造方法,Java系统会自动生成一个不带参数的构造方法用于创建实例,这个方法就是默认构造方法。在具有自定义构造方法的类体中,如果调用了默认构造方法来创建实例,那么默认构造方法必须显式地书写在类体中,不能省略。实例如下所示。 【例24】定义Person类。 class Person{ private String name ;// 声明姓名属性 private int age ;// 声明年龄属性 public Person(){}// 声明无参的构造方法 public Person(String n){// 声明有参数的构造方法,为name属性赋值 thissetName(n) ; } public Person(String n,int a){// 声明构造方法,为类中的属性初始化 thissetName(n) ;// 为name属性赋值 thissetAge(a) ;// 为age属性赋值 } public void setName(String n){// 设置姓名 name = n ; } public void setAge(int a){// 设置年龄 if(a>0&&a<150){ age = a ; } } public String getName(){// 获取姓名 return name ; } public int getAge(){// 获取年龄 return age ; } public void tell(){// 获取信息 Systemoutprintln("姓名:" + thisgetName() + ",年龄:" + thisgetAge()) ; } } public class ExampleDemo03{ public static void main(String args\[\]){ Person per = new Person("孙莉娜",30) ;// 调用带参数的构造方法实例化对象 pertell() ;// 输出信息 } } 【运行结果】 姓名:孙莉娜,年龄:30 读者可以自行尝试调用不带参数的构造方法和带一个参数的构造方法,查看相关结果。 知识点八:对象的创建与使用 如果把程序设计比作一项建筑工程,完成类定义相当于设计出施工图纸。根据一张图纸可以建起多座建筑物,同样,可以为每个类创建多个对象。 1创建对象 类是一种数据类型,对象相当于这种数据类型的变量,它在使用前要先定义或声明。例如对于上面定义的Person类,要声明一个per对象,使用语句Person per;。 声明类的对象之后,并没有创建该对象,此时对象的值为null。这和定义基本类型的变量相似,不同之处在于:基本数据类型的变量在声明之后,即使没有初始化,变量有一个初始值,如整型变量的初始值为0,布尔型变量的初始值为false;而类对象的初始值却为null。要想让对象指向某一具体值,需要用类的构造方法创建对象。 以per为例,创建方法如下:per = new Person("孙莉娜",30);。 也可以在声明对象的同时创建该对象,例如Person per = new Person("孙莉娜",30);。 2使用对象 声明变量是为了在程序中使用变量,同样创建对象也是为了使用对象。同基本类型变量不同之处在于:基本类型的变量包含的信息相对简单,而对象中包含了属性和处理属性的方法。使用对象属性和方法,采用以下形式:对象名称属性或方法。之前例22已显示使用方法。当然也可以同时创建多个对象,每个对象会分别占据自己的空间,实例如下所示。 【例25】定义Student类,改造例22。 class Student{ int age;// 声明年龄属性 void getAge(){// 获取年龄方法 Systemoutprintln("学生年龄:"+age) ;// 输出年龄值 } } public class ExampleDemo02{ public static void main(String args\[\]){// 主方法,程序入口点 Student stu1 = new Student() ;// 声明学生1对象 Student stu2 = new Student() ;// 声明学生2对象 stu1age=30; stu1getAge() ;// 引用学生1对象方法,显示年龄 stu2age=20; stu2getAge() ;// 引用学生2对象方法,显示年龄 } } 【运行结果】 学生年龄:30 学生年龄:20