第2章预备知识 2.1 Java程序设计基础 J a v a是J S P的基础,要学习J S P技术,J a v a基础是必不可少的。本节将简要介绍J a v a的基本语 法和概念。已经是J a v a编程人员的读者就不用阅读了,这里是为没有多少J a v a经验的读者提供一 个快速入门的方法。这里对J a v a语言的介绍仅仅是一个基本的概况,要想深入学习J S P,必须对 J a v a语言有深刻的理解,笔者推荐机械工业出版社翻译出版的《J a v a编程思想》一书,本书限于 篇幅,就不多讲了。 2.1.1 Java语言规则 J a v a语言的基本结构像C / C + +, 任何用面向过程语言编写过程序的人都可以了解J a v a语言的 大部分结构。 1. 程序结构 J a v a语言的源程序代码由一个或多个编译单元( c o m p i l a t i o n u n i t )组成,每个编译单元只能包 含下列内容(空格和注释除外): • 程序包语句(package statement )。 • 入口语句(import statements) 。 • 类的声明(class declarations) 。 • 界面声明(interface declarations)。 每个J a v a的编译单元可包含多个类或界面,但是每个编译单元最多只能有一个类或者界面是 公共的。Java 的源程序代码被编译后,便产生了J a v a字节代码。J a v a的字节代码由一系列不依 赖于机器的指令组成,这些指令能被J a v a的运行系统(runtime system)有效地解释。J a v a的运行系 统工作起来如同一台虚拟机。在当前的J a v a实现中,每个编译单元就是一个以. j a v a为后缀的文件。 每个编译单元有若干个类,编译后,每个类生成一个. c l a s s文件。. c l a s s文件是J a v a虚拟机能够识 别的代码。在引入了J A R这个概念以后,现在可以把许多J a v a的c l a s s文件压缩进入一个J A R文件 中。新版本的J a v a已经可以直接读取J A R文件加以执行。 2. 注释 注释有三种类型: / / 注释一行 / * 一行或多行注释 */ / * * 文档注释 **/ 文档注释一般放在一个变量或函数定义之前,表示在任何自动生成文档系统中调入,提取 注释生成文档的工具叫做j a v a d o c,其中还包括一些以@开头的变量,如: @ s e e、@ v e r s i o n、 @ p a r a m等等,具体用法参见J D K自带的工具文档。 3. 标识符 变量、函数、类和对象的名称都是标识符,程序员需要标识和使用的东西都需要标识符。 在J a v a语言里,标识符以字符_或$开头,后面可以包含数字,标识符是大小写有区别的,没有长 度限制。 有效的标识符如: gogogo brood_war Hello _and_you $bill。 声明如: int a_number; char _onechar; float $bill。 以下为J a v a的关键字: a b s t r a c t c o n t i n u e f o r new switch b o o l e a n d e f a u l t g o t o n u l l synchronized b r e a k d o i f p a c k a g e this b y t e d o u b l e i m p l e m e n t s p r i v a t e threadsafe b y v a l u e e l s e i m p o r t p r o t e c t e d throw c a s e e x t e n d s i n s t a n c e o f p u b l i c transient c a t c h f a l s e i n t r e t u r n true char f i n a l i n t e r f a c e short try c l a s s f i n a l l y l o n g s t a t i c void c o n s t f l o a t n a t i v e s u p e r while 以下单词被保留使用: c a s t、f u t u r e、g e n e r i c、i n n e r、o p e r a t o r、o u t e r、r e s t、v a r。 4. 数据类型 J a v a使用五种基本类型: i n t e g e r (整数),f l o a t i n g (浮点数),p o i n t (指针),B o o l e a n (布尔变量), Character or String(字符或字符串)。此外,还有一些复合的数据类型,如数组等。 Integer 包含下面几种类型: 整数长度( B i t s ) 数据类型表示 8 b y t e 1 6 short 3 2 int 6 4 l o n g floating 下边给出的数据表示都是浮点数的例子: 3 . 1 4 1 5 9,3 . 1 2 3 E 1 5,4 e 5 浮点数长度(Bits) 数据类型表示 3 2 f l o a t 6 4 double Boolean 下边是布尔变量的两种可能取值: t r u e false Character 下边给出的都是字符的例子: 第二章预备知识17
a s d f String 下边给出的都是字符串的例子: 'gogogo,rock and roll' ' J S P高级编程' 数组可以定义任意类型的数组,如char s[],这是字符型数组; int array [],这是整型数组; 还可以定义数组的数组. intblock[][]=new int [2][3];数组边界在运行时被检测,以避免堆栈溢出。 在J a v a里,数组实际上是一个对象,数组有一个成员变量: l e n g t h。可以用这个成员函数来 查看任意数组的长度。 在J a v a里创建数组,可使用两种基本方法: 1) 创建一个空数组。 int list[]=new int[50]; 2) 用初始数值填充数组. String names[] = { 'Chenji','Yuan','Chun','Yang' }; 它相当于下面功能: String names[]; names = new String[4]; names[0]=new String('Chenji'); names[1]=new String('Yuan'); names[2]=new String('Chun'); names[3]=new String('Yang'); 在编译时不能这样创建静态数组: int name[50]; / /将产生一个编译错误 也不能用n e w操作去填充一个没定义大小的数组。如: int name[]; for (int i=0;i<9; i++) { name[i] = i; } 5. 表达式 J a v a语言的发展中有许多是从C语言借鉴而来的,所以J a v a的表达式和C语言非常类似。 运算符 运算符( o p e r a t o r )优先级从高到低排列如下: . [ ] () ++ -- ! ~ instanceof * / % + - << >> >>> < > <= > == ! = & ^ && || ? : = op = , (2) 整数运算符 在整数运算时,如果操作数是l o n g类型,则运算结果是l o n g类型,否则为i n t类型,绝不会是 b y t e,s h o r t或c h a r型。这样,如果变量i被声明为s h o r t或b y t e,i + 1的结果会是i n t。如果结果超过 该类型的取值范围,则按该类型的最大值取模。单目整数运算符是: 运算符操作 - 非 ~ 位补码 + + 加1 - - 减1 18第一部分JSP 入门
+ +运算符用于表示直接加1操作。增量操作也可以用加运算符和赋值操作间接完成。+ + lvalue (左值表示l v a l u e + = 1, ++lvalue 也表示lvalue =lvalue +1 (只要l v a l u e没有副作用)。- -运 算符用于表示减1操作。+ +和- -运算符既可以作为前缀运算符,也可以作为后缀运算符。双目 整数运算符是: 运算符操作 + 加 - 减 * 乘 / 除 % 取模 & 位与 | 位或 ^ 位异或 < < 左移 > > 右移(带符号) > > > 添零右移 整数除法按零舍入。除法和取模遵守以下等式: ( a/b ) * b + ( a%b ) == a。整数算术运算的 异常是由于除零或按零取模造成的。它将引发一个算术异常,下溢产生零,上溢导致越界。例 如:加1超过整数最大值,取模后,变成最小值。一个o p =赋值运算符,和上表中的各双目整数 运算符联用,构成一个表达式。整数关系运算符<,>,< =,> =,= =和! =产生b o o l e a n类型的数 据。 ( 3 ) 布尔运算符 布尔( b o o l e a n )变量或表达式的组合运算可以产生新的b o o l e a n值。单目运算符!是布尔非。 双目运算符&、|和^是逻辑A N D、O R和X O R运算符,它们强制两个操作数求布尔值。为避免 右侧操作数冗余求值,用户可以使用短路求值运算符&& 和||。用户可以使用= =和! =,赋值 运算符也可以用& =、| =、^ =。三元条件操作符? : 和C语言中的一样。 (4) 浮点运算符 浮点运算符可以使用常规运算符的组合,如单目运算符+ +、- -,双目运算符+、-、* 和/, 以及赋值运算符+ =,- =,* =,和/ =。此外,还有取模运算:%和% =也可以用于浮点数,例如: a % b和a-((int) (a/b)*b)的语义相同。这表示a % b的结果是除完后剩下的浮点数部分。只有单精度 操作数的浮点表达式按照单精度运算求值,产生单精度结果。如果浮点表达式中含有一个或一 个以上的双精度操作数,则按双精度运算,结果是双精度浮点数。 (5) 数组运算符 数组运算符形式如下: <expression> [ <expression>] 可给出数组中某个元素的值。合法的取值范围是从0到数组的长度减1。取值范围的检查只 在运行时刻实施。 ( 6 ) 对象运算符 双目运算符instanceof 测试某个对象是否是指定类或其子类的实例。例如: if (myObject instanceof MyClass) { 第二章预备知识19
MyClass anothermyObject=( MyClass) myObject; ... } 是判定m y O b j e c t是否是M y C l a s s的实例或是其子类的实例。 (7) 强制和转换 J a v a语言和解释器限制使用强制和转换,以防止出错导致系统崩溃。整数和浮点数间可以来 回强制转换,但整数不能强制转换成数组或对象。对象不能被强制为基本类型。 6. Java流控制 下面几个控制结构是从C语言借鉴的。 ( 1 ) 分支结构 i f / e l s e分支结构: if (Boolean) { statemanets; } else { statements; } s w i t c h分支结构: switch(expr1) { case expr2: statements; break; case expr3: statements; break; default: statements; break; } (2) 循环结构 f o r循环结构: for (init expr1;test expr2;increment expr3) { statements; } W h i l e循环结构: While(Boolean) { statements; } D o循环结构: do statements; } while (Boolean); 20第一部分JSP 入门
2.1.2 Java变量和函数 J a v a的类包含变量和函数。数据变量可以是原始的类型,如i n t、c h a r等。成员函数是可执行 的过程。例如,下面的程序: public class TestClass public TestClass () { i=10; } public void addI(int j) { i=i+j; } } Te s t C l a s s包含一个变量i和两个成员函数,TestClass(int first)和addI(int j)。 成员函数是一个可被其他类或自己类调用的处理子程序。一个特殊的成员函数叫构造函数, 这个函数名称一般与本类名称相同。它没有返回值。 在J a v a里定义一个类时,可定义一个或多个可选的构造函数,当创建本类的一个对象时,用 某一个构造函数来初始化本对象。用前面程序例子来说明,当Te s t C l a s s类创建一个新实例时, 所有成员函数和变量被创建(创建实例)。构造函数被调用。 TestClass testObject; testObject = new TestClass(); 关键词n e w用来创建一个类的实例,一个类用n e w初始化前并不占用内存,它只是一个类型 定义,当t e s t O b j e c t对象初始化后,t e s t O b j e c t对象里的i变量等于1 0。可以通过对象名来引用变量 i。(有时称为实例变量) testObject.i++;// testObject实例变量加1,因为t e s t O b j e c t有Te s t C l a s s类的 所有变量和成员函数,可以使用同样的语法来调用成员函数a d d I:addI(10); 现在t e s t O b j e c t . i变 量等于2 1。 J a v a并不支持析构函数( C + +里的定义),因为j a v a对象无用时,有自动清除的功能,同时它 也提供了一个自动垃圾箱的成员函数,在清除对象时被调用: Protected void finalize() { close(); } 2.1.3 子类 子类是利用存在的对象创建一个新对象的机制,比如,如果有一个H o r s e类,你可以创建一 个Z e b r a子类,Z e b r a是H o r s e的一种。 class Zebra extends Horse { int number_OF_stripes: } 关键词e x t e n d s来定义对象有的子类. Z e b r a是H o r s e的子类。H o r s e类里的所有特征都将拷贝到 Z e b r a类里,而Z e b r a类里可以定义自己的成员函数和实例变量。Z e b r a称为H o r s e的派生类或继承。 另外,你也许还想覆盖基类的成员函数,可用Te s t C l a s s说明,下面是一派生类覆盖A d d I功能的 例子。 import TestClass; public class NewClass extends TestClass { 第二章预备知识21
public void AddI(int j) { i=i+(j/2); } } 当N e w C l a s s类的实例创建时,变量i初始化值为1 0,但调用A d d I产生不同的结果。 NewClass newObject; newObject=new NewClass(); newObject.AddI(10); 当创建一个新类时,可以标明变量和成员函数的访问层次。 public public void AnyOneCanAccess(){} public实例变量和成员函数可以由任意其他类调 用。 protected protected void OnlySubClasses(){} protected实例变量和成员函数只能被其子类调 用。 private private String CreditCardNumber; private实例变量和成员函数只能在本类里调用。 friendly void MyPackageMethod(){}是缺省的,如果没有定义任何访问控制,实例变量或函 数缺省定义成f r i e n d l y,这意味着可以被本包里的任意对象访问,但其他包里的对象不可访问。 对于静态成员函数和变量,有时候,你创建一个类,希望这个类的所有实例都公用一个变 量。就是说,所有这个类的对象都只有实例变量的同一个拷贝。这种方法的关键词为s t a t i c, 例 如: class Block { static int number=50; } 所有从B l o c k类创建的对象的n u m b e r变量值都是相同的。无任在哪个对象里改变了n u m b e r的 值, 所有对象的n u m b e r都跟着改变。同样,可以定义s t a t i c成员函数,但这个成员函数不能访问 非s t a t i c函数和变量。 class Block { static int number = 50; int localvalue; static void add_local(){ localvalue++; file://没/有运行 } static void add_static() { number++;//运行 } } 2.1.4 this和s u p e r 访问一个类的实例变量时, t h i s关键词是指向这个类本身的指针,在前面的Te s t C l a s s例子中, 可以增加构造函数如下: public class TestClass {
|