第2章MiniJOOL语言 ∥第一个类是主类,必须有主方法mair ∥Son类:提供目泡排序 class Program class Sort! static void main() ∥实例变量 Sort qs=new QuickSort() int0data={4,76,5,234,7} gs.sort() /∥交换datali]和datalil qs=new Sort(). void swap(inti,intj){ qs.sort(). int temp=data[可: return; datali=datali: dataj]=temp: ∥QuickSort类继承自Sort,提供快速排序 ∥对daa中的数进行排序 class QuickSort extends Sort{ void sortO void sort() int i=data.length-1; qsort(0,data length-1). while(i>0)! int j=0: int partition(int low,int high) while(j<i){ int pivot=data[low]; if(data[>dataj+ int i=low-1; swap(i,+ intj=high+1. while(i<j){ j=j+, i+: while (ai]<pivot)+ i-i-1; while (a[j]>pivot)j if(i<j)swap(i.j). ∥打印data中的数 void printArray() returnj方 inti=0 String str ="nMember:". void gsort(int low,int high) while (i<data.length) if(low>=high)return: print(str)print()print("is int p=partition(low,high) print(datai]): gsort(a.low.p). qsort(a,p+1.high). 图2-1 MiniJOOL程序示例:冒泡排序和快速排序
第 2 章 MiniJOOL 语言 25 // 第一个类是主类,必须有主方法 main class Program{ static void main( ) { Sort qs = new QuickSort(); qs.sort( ); qs = new Sort(); qs.sort( ); return; } } // QuickSort 类继承自 Sort,提供快速排序 class QuickSort extends Sort { void sort() { qsort(0, data.length - 1); } int partition(int low, int high) { int pivot = data[low]; int i = low-1; int j = high+1; while (i < j) { i++; while (a[i] < pivot) i++; j--; while (a[j] > pivot) j--; if (i < j) swap(i, j); } return j; } void qsort(int low, int high) { if (low >= high) return; int p = partition(low, high); qsort(a, low, p); qsort(a, p + 1, high); } } // Sort 类:提供冒泡排序 class Sort{ // 实例变量 int[] data = {4,76,5,234,7}; // 交换 data[i]和 data[j] void swap(int i, int j) { int temp = data[i]; data[i] = data[j]; data[j] = temp; } // 对 data 中的数进行排序 void sort (){ int i = data.length – 1; while(i >= 0){ int j = 0; while(j < i){ if (data[j] > data[j+1]){ swap(j, j+1); } j = j + 1; } i = i - 1; } } // 打印 data 中的数 void printArray() { int i = 0; String str = “\nMember:”; while (i < data.length) { print(str); print(i); print(“is ”); print(data[i]); } } } 图 2-1 MiniJOOL 程序示例:冒泡排序和快速排序
第2章Min0OL语言 3、常量值 MiniJOOL语言的值包括整型值、布尔值、空引用和字符串。 注意:MiniJOOL语言中没有字符常量。 整型值有十进制数、八进制数、十六进制数几种形式。MiniJOOL语言规定,凡是以数 字0开头的数字序列,一律作为八进制数处理:凡是以0x或0X开头,后面跟若干位数字 的,一律作为十六进制数处理。 布尔值有true和false两个:空引用为null。 字符串是由一对双引号括起来的零个或多个字符组成的字符序列,这里的字符指的是 个单独的ASCI字符,除去控制字符(ASCI码为031)、双引号(ASCI码为34)、反斜 杠(ASCI码为92)和Delete健(ASCI码为127):或者是一个双字符的合法转义序列, 即反斜杠后跟一个双引号、反斜杠、字母n、字母r、字母t或空格。MiniJOOL语言不考虑 反斜杠后跟数字的转义序列。 4、关键字(保留字) MiniJOOL语言包含如下关键字,这些关键字都作为保留字使用: class static final extends void int boolean String if else while break continue return print read new this super instanceof null true false 5、标识符 MiniJOOL语言中的标识符是以字母('A'~Z或a~z)开始的,由字母、数字(0~9)、 下划线)组成的字符串。 6、分隔符 (){}[】;, 7、运算符 && % % 2.3 MiniJOOL语言的语法 个MiniJOOL程序由一个或多个类声明组成,其中第一个是主类。主类中必须含有 个类型为static void的main方法,它是MiniJOOL程序的入口。在以下各小节中,将从类型、 值、变量、类、语句块和语句、表达式几方面,结合EBNF形式来描述MiniJOOL语言的语 3根据1S0MEC1497: 6E)提定的EBNF语法 acukt-mgk25 号括起,包含在 一对方括号内的部分为可选符号,包含在一对花括号内的部分表示该部分重 0次或多次
第 2 章 MiniJOOL 语言 26 3、常量值 MiniJOOL 语言的值包括整型值、布尔值、空引用和字符串。 注意:MiniJOOL 语言中没有字符常量。 整型值有十进制数、八进制数、十六进制数几种形式。MiniJOOL 语言规定,凡是以数 字 0 开头的数字序列,一律作为八进制数处理;凡是以 0x 或 0X 开头,后面跟若干位数字 的,一律作为十六进制数处理。 布尔值有 true 和 false 两个;空引用为 null。 字符串是由一对双引号括起来的零个或多个字符组成的字符序列。这里的字符指的是一 个单独的 ASCII 字符,除去控制字符(ASCII 码为 0~31)、双引号(ASCII 码为 34)、反斜 杠(ASCII 码为 92)和 Delete 键(ASCII 码为 127);或者是一个双字符的合法转义序列, 即反斜杠后跟一个双引号、反斜杠、字母 n、字母 r、字母 t 或空格。MiniJOOL 语言不考虑 反斜杠后跟数字的转义序列。 4、关键字(保留字) MiniJOOL 语言包含如下关键字,这些关键字都作为保留字使用: class static final extends void int boolean String if else while break continue return print read new this super instanceof null true false 5、标识符 MiniJOOL 语言中的标识符是以字母('A'~'Z'或'a'~'z')开始的,由字母、数字('0'~'9')、 下划线('_')组成的字符串。 6、分隔符 ( ) { } [ ] ; , . 7、运算符 > < == <= >= != ! && || + - * / % = += -= *= /= %= 2.3 MiniJOOL 语言的语法 一个MiniJOOL程序由一个或多个类声明组成,其中第一个是主类。主类中必须含有一 个类型为static void的main方法,它是MiniJOOL程序的入口。在以下各小节中,将从类型、 值、变量、类、语句块和语句、表达式几方面,结合EBNF形式 3 来描述MiniJOOL语言的语 3 根据 ISO/IEC 14977:1996(E)规定的 EBNF 语法(http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html),其中 终结符用引号括起,包含在一对方括号内的部分为可选符号,包含在一对花括号内的部分表示该部分重复 0 次或多次
第2章MiniJOOL语言 法,其中除标识符和常量值以外的终结符都直接用其对应的字符串值来表示。 2.3.1类型、值和变量 2.3.1.1类型和值 除了void类型外,MiniJOOL语言中的类型有int(32位)、boolean、String、数组类型 以及在当前程序中声明的类类型。与Java语言不同的是,这里的数组类型是一维的并且必 须静态地确定所声明的数组的长度,但是当数组作为形参时不必指定其长度。下面的EBNF 式中的constant_expression必须在编译时能求得为一个正整数, type primitive_type"String"array_type class_type primitive_type=“int”"boolean” array_type =(primitive_type"String")"[constant_expression]" constant expression expression class_type=IDENTIFIER 此外,MiniJOOL语言中还有一个特殊的空引用类型,它是表达式nul的类型,这个空 引用类型没有名字。由于空引用类型没有名字,所以不可能声明一个空引用类型的变量。对 一般的程序员来说,可以忽略空引用类型,而只把当成是一个可以为任何引用类型的 特殊值。 与上述类型相对应,MiiO0L语言中的值有整型值、布尔值、空引用和字符串四类, 在22节中给出了它们的构成特征。 literal INTEGER_LITERAL BOOLEAN_LITERAL ISTRING_LITERALINULL_LITERAL 在下面各小节中,将介绍MOOL语言中各种类型的取值以及在值上能讲行的运算。 关于各种类型的变量及其赋值以及函数参数传递机制将在2.3.12节中说明。 1、整型及其值 MiniJ(00L语言的imt型占4个字节,是有符号整型,其值的取值范围在-2147483648到 2147483647之间。MiniJO0L语言提供以下在整型值上的运算: ·比较运算,其结果为boolean型值 ■数值比较运算符:<、<云、>、 ■数值相等运算符:=和=: ·算术运算,其结果为it型值 ·一元的正、负运算符:+和- ■乘除运算符:◆(乘)、/(整除)和%(求余): ■加减运算符:+和-。 2、布尔型及其值 boolean型表示两种可能的值:truc和alsc。boolean型值在内存中的表示由编译器决定。 MiniJOOL语言提供以下在boolean值上的运算:
第 2 章 MiniJOOL 语言 27 法,其中除标识符和常量值以外的终结符都直接用其对应的字符串值来表示。 2.3.1 类型、值和变量 2.3.1.1 类型和值 除了 void 类型外,MiniJOOL 语言中的类型有 int(32 位)、boolean、String、数组类型 以及在当前程序中声明的类类型。与 Java 语言不同的是,这里的数组类型是一维的并且必 须静态地确定所声明的数组的长度,但是当数组作为形参时不必指定其长度。下面的 EBNF 式中的 constant_expression 必须在编译时能求得为一个正整数。 type = primitive_type | “String” | array_type | class_type primitive_type = “int” | “boolean” array_type = (primitive_type | “String”) “[” [ constant_expression ] “]” constant_expression = expression class_type = IDENTIFIER 此外,MiniJOOL 语言中还有一个特殊的空引用类型,它是表达式 null 的类型,这个空 引用类型没有名字。由于空引用类型没有名字,所以不可能声明一个空引用类型的变量。对 一般的程序员来说,可以忽略空引用类型,而只把 null 当成是一个可以为任何引用类型的 特殊值。 与上述类型相对应,MiniJOOL语言中的值有整型值、布尔值、空引用和字符串四类, 在 2.2 节中给出了它们的构成特征。 literal = INTEGER_LITERAL | BOOLEAN_LITERAL | STRING_LITERAL | NULL_LITERAL 在下面各小节中,将介绍MiniJOOL语言中各种类型的取值以及在值上能进行的运算。 关于各种类型的变量及其赋值以及函数参数传递机制将在 2.3.1.2 节中说明。 1、整型及其值 MiniJOOL 语言的 int 型占 4 个字节,是有符号整型,其值的取值范围在-2147483648 到 2147483647 之间。MiniJOOL 语言提供以下在整型值上的运算: z 比较运算,其结果为 boolean 型值 数值比较运算符:<、<=、>、>=; 数值相等运算符:==和!=; z 算术运算,其结果为 int 型值 一元的正、负运算符:+和-; 乘除运算符:*(乘)、/(整除)和%(求余); 加减运算符:+和-。 2、布尔型及其值 boolean 型表示两种可能的值:true 和 false。boolean 型值在内存中的表示由编译器决定。 MiniJOOL 语言提供以下在 boolean 值上的运算:
第2章MiniJOOL语言 ●关系运算符:==和=: ·逻辑运算符:!(逻辑非)、&&(逻辑与)和川(逻辑或)。 boolean表达式可以决定if、while语句的控制流。 3、字符串型及其值 这里要区分String型常量和String型变量。String型常量是由一对双引号括起来的零个或 多个字符组成的字符序列。一个长度为n.(0)的字符串在内存中将占+1个字节,最后一 个字节存放的ASCI码值是0。Stig型变量的值是一个引用值,它引用一个字符串常量 MiniJOOL语言在字符串值上不提供任何运算,而关于String型变量的运算在2.3.1.2节中说 明。 4、数组类型及其值 MiniJ0L语言要求在声明数组时静态确定数组的长度,如“int[2a”、“int]a={l,2:” 或“in2】a=1,2:”,并且允许通过“<数组名>.length”获得给定数组的长度,如a.length 的值是2。MiniJOOL语言不提供在数组整体上的运算,只允许对数组元素值进行运算。对 数组元素的访问可通过数组名加下标表达式来进行,如a1.MiniJOOL语言规定,对于 个长度为N的数组,其元素的下标取值范围为从0到N-1的整数。 5、类类型及其值 类类型是引用类型。类的一个实例(instance)称为一个对象(object)。引用值是指向 对象的指针,而特殊的空引用不指向任何对象。一个类实例是由w表达式显式创建的. MiniJOOL语言提供以下在对象引用上的运算符: ·域访问:使用受限名或域访问表达式来进行: ·方法调用 ·instanceof运算符 ·引用相等运算符:=和= 同一个对象可以有多个引用。对象的状态存储在对象的域中,如果两个变量包含对同 个对象的引用,则可以通过其中一个变量来修改对象的状态,随后另一个变量也可以通过引 用观察到改变后的状态。图2-2给出了关于类类型及其值使用的程序示例。 class Program{ static void main() Aal=newA(方∥创建类A的一个对象 Aa2=al: ∥a2和al指向同一个类A的对象 Bb=new B(); ∥创建类B的一个对象 print(A.si:∥域访问:类名A作为受限名,输出“2” print(al.si,∥域访问:类类型变量al作为受限名,输出“2 print(al.i,∥域访问:类类型变量al作为受限名,输出“4” af0). ∥类方法调用,打印“A” 28
第 2 章 MiniJOOL 语言 28 z 关系运算符:==和!=; z 逻辑运算符:!(逻辑非)、&&(逻辑与)和||(逻辑或)。 boolean 表达式可以决定 if、while 语句的控制流。 3、字符串型及其值 这里要区分String型常量和String型变量。String型常量是由一对双引号括起来的零个或 多个字符组成的字符序列。一个长度为n(n>0)的字符串在内存中将占n+1 个字节,最后一 个字节存放的ASCII码值是 0。String型变量的值是一个引用值,它引用一个字符串常量。 MiniJOOL语言在字符串值上不提供任何运算,而关于String型变量的运算在 2.3.1.2 节中说 明。 4、数组类型及其值 MiniJOOL 语言要求在声明数组时静态确定数组的长度,如“int[2] a;”、“int[] a={1,2};” 或“int[2] a={1,2};”,并且允许通过“<数组名>.length”获得给定数组的长度,如 a.length 的值是 2。MiniJOOL 语言不提供在数组整体上的运算,只允许对数组元素值进行运算。对 数组元素的访问可通过数组名加下标表达式来进行,如 a[1]。MiniJOOL 语言规定,对于一 个长度为 N 的数组,其元素的下标取值范围为从 0 到 N-1 的整数。 5、类类型及其值 类类型是引用类型。类的一个实例(instance)称为一个对象(object)。引用值是指向 对象的指针,而特殊的空引用不指向任何对象。一个类实例是由 new 表达式显式创建的。 MiniJOOL 语言提供以下在对象引用上的运算符: z 域访问:使用受限名或域访问表达式来进行; z 方法调用 z instanceof 运算符 z 引用相等运算符:==和!=。 同一个对象可以有多个引用。对象的状态存储在对象的域中。如果两个变量包含对同一 个对象的引用,则可以通过其中一个变量来修改对象的状态,随后另一个变量也可以通过引 用观察到改变后的状态。图 2-2 给出了关于类类型及其值使用的程序示例。 class Program { static void main() { A a1 = new A( ); // 创建类 A 的一个对象 A a2 = a1; // a2 和 a1 指向同一个类 A 的对象 B b = new B( ); // 创建类 B 的一个对象 print(A.si); // 域访问:类名 A 作为受限名,输出“2” print(a1.si); // 域访问:类类型变量 a1 作为受限名,输出“2” print(a1.i); // 域访问:类类型变量 a1 作为受限名,输出“4” a.f(); // 类方法调用,打印“A
第2章MiniJOOL语言 print(al instanceofA,)∥判断al引用的对象是否为类A的实例。输出“tnue print((al instanceof B,头∥判断al引用的对象是否为类B的实例。输出“false" print(al==a2上:/∥判断a1和a2是否引用同一个对象。输出“tnue print(al-b),∥判断al和b是否引用同一个对象。输出“alse” 31i=8 ∥通过al修改实例变量i pin(a2.i∥通过a2访问同一实例变量】 class A static int si=2: ∥si是米变品 inti= i是实例变量 void f) print("A"方 class B 图2-2 MiniJ00L程序示例:类类型及其值 23.1.2变量 一个变量是一个存储单元,它有关联的类型。变量总是被赋予一个与其类型相兼容的值, 关于MiniJO0L语言的类型兼容原则在2.3.1.3节说明。 下面结合图2-3中的代码片段来简要说明变量的种类、初始化以及其他使用特征。你 可以阅读2.32和2.34节获得关于变量在类以及表达式中使用的更详细信息。 class VariousVariables static final int n=5; ∥声明一个带初始化表达式的inal类变量 static int m: ∥声明一个不带初始化表达式的类变量m int x.y=8; ∥x和y是实例变量,声明y时带初始化表达式 int[10]w. ∥声明一个长度为10的数组实例变量 int 10 wl =w. ∥产生编译时错误,不能将数组赋值给一个数组变量 VariousVariables(ntm){∥ml是该构造器的形参 m=ml: int setX(int x) ∥x是方法setX的形参 int oldx=this.x:∥oldx是局部变最 this.x=x; ∥通过his.x引用实例变量x w[x%10]=x ∥通过w和下标表达式x%10来引用数组元素 returnoldx;
第 2 章 MiniJOOL 语言 29 print(a1 instanceof A); // 判断 a1 引用的对象是否为类 A 的实例。输出“true” print(a1 instanceof B); // 判断 a1 引用的对象是否为类 B 的实例。输出“false” print(a1==a2); // 判断 a1 和 a2 是否引用同一个对象。输出“true” print(a1==b); // 判断 a1 和 b 是否引用同一个对象。输出“false” a1.i = 8; // 通过 a1 修改实例变量 i print(a2.i); // 通过 a2 访问同一实例变量 i } } class A { static int si = 2; // si 是类变量 int i = 4; // i 是实例变量 void f() { print("A"); } } class B { } 图 2-2 MiniJOOL 程序示例:类类型及其值 2.3.1.2 变量 一个变量是一个存储单元,它有关联的类型。变量总是被赋予一个与其类型相兼容的值。 关于MiniJOOL语言的类型兼容原则在 2.3.1.3 节说明。 下面结合 图 2-3 中的代码片段来简要说明变量的种类、初始化以及其他使用特征。你 可以阅读 2.3.2 和 2.3.4 节获得关于变量在类以及表达式中使用的更详细信息。 class VariousVariables{ static final int n = 5; // 声明一个带初始化表达式的 final 类变量 n static int m; // 声明一个不带初始化表达式的类变量 m int x, y=8; // x 和 y 是实例变量,声明 y 时带初始化表达式 int[10] w; // 声明一个长度为 10 的数组实例变量 int[10] w1 = w; // 产生编译时错误,不能将数组赋值给一个数组变量 VariousVariables(int m1) { // m1 是该构造器的形参 m = m1; } int setX(int x){ // x 是方法 setX 的形参 int oldx = this.x; // oldx 是局部变量 this.x = x; // 通过 this.x 引用实例变量 x w[x%10] = x; // 通过 w 和下标表达式 x%10 来引用数组元素 return oldx;