Java语言规格说明1程序结构Java语言的源程序代码由一个或多个编译单元.doc

上传人:rrsccc 文档编号:9198286 上传时间:2021-02-07 格式:DOC 页数:13 大小:50KB
返回 下载 相关 举报
Java语言规格说明1程序结构Java语言的源程序代码由一个或多个编译单元.doc_第1页
第1页 / 共13页
Java语言规格说明1程序结构Java语言的源程序代码由一个或多个编译单元.doc_第2页
第2页 / 共13页
Java语言规格说明1程序结构Java语言的源程序代码由一个或多个编译单元.doc_第3页
第3页 / 共13页
Java语言规格说明1程序结构Java语言的源程序代码由一个或多个编译单元.doc_第4页
第4页 / 共13页
Java语言规格说明1程序结构Java语言的源程序代码由一个或多个编译单元.doc_第5页
第5页 / 共13页
点击查看更多>>
资源描述

《Java语言规格说明1程序结构Java语言的源程序代码由一个或多个编译单元.doc》由会员分享,可在线阅读,更多相关《Java语言规格说明1程序结构Java语言的源程序代码由一个或多个编译单元.doc(13页珍藏版)》请在三一文库上搜索。

1、Java语言规格说明 1.程序结构 Java语言的源程序代码由一个或多个编译单元(compilation unit)组成,每个编译单元只能包含下列内容(空格和注释除外): * 一个程序包语句(package statement ) * 引入语句(import statements) * 类的声明(class declarations) * 界面声明(interface declarations) 每个Java的编译单元可包含多个类或界面,但是每个编译单元却至多有一个类或者界面是公共的。 Java 的源程序代码被编译之后,便产生了Java字节代码(bytecode)。Java的字节代码由一些不依

2、赖于机器的指令组成,这些指令能被Java的运行系(runtime system)有效地解释。Java的运行系统工作起来如同一台虚拟机。 在当前的Java实现中,每个编译单元就是一个以.java为后缀的文件。每个编译单元有若干个类,编译后,每个类生成一个.class文件。.class文件是Java虚机器码。 2. 词法问题 在编译的过程中,Java源程序代码中的字符被划分为一系列的标记(token)。Java编译器可以识别五种标记: 标识符、关键字、字面量、运算符以及特殊分隔符。注释以及诸如空格、制表符、换行符等字符 ,都不属于标识之列,但他们却常被用来分隔标记。 Java程序的编写采用泛代码U

3、nicode字符集,若采用其它的字符集,则需在编译前转换成Unicode。 2.1 注释 Java语言提供了3种形式的注释: /text 从/到本行结束的所有字符均作为注释而被编译器忽略。 /* text */ 从/*到*/ 间的所有字符会被编译器忽略。 /* text */ 当这类注释出现在任何声明之前时将会作特殊处理,它们不能再用在代码的任何地方。这类注释意味着被括起来的正文部分,应该作为声明项目的描述,而被包含在自动产生的文档中。 2.2 标识符 标识符的首字符必须是一个字母,下划线(_)或美元符号($)。 后面的字符也可是数字0-9。 Java使用泛代码字符集,为了便于识别好一合法标识

4、符,下面列出它的“字母”: * 大写字母“A”“Z” * 小写字母“a”“z” * 泛代码(Unicode)中所有字符编码在十六进制数00C0之前的字符。标识符中,首字母后的字符可以是任意的。当然,Unicode区段中那些被保留作特殊字符的除外。由此,“garton”及“Mjlner”都是合法标识符,但是,包括诸如“”的字符串却不是合法的。 2.3 关键字 下面的标识符被保留用作关键字,他们不能作任何其它的用途。 abstract default goto* null synchronized boolean do if package this break double implements

5、 private threadsafe byte else import protected throw byvalve * extends instanceof public transient case false int return true catch final interface short try char finally long static void class float native super while const * for new switch continue 其中,加*标记后是被保留但当前却未使用的。 2.4 字面量 字面量(literal)是某些类型值的

6、基本表述,这些类型包括整型,浮点型,布尔量,字符及字符串。 2.4.1 整型字面量 整数可有三种表示形式: 十进制,八进制和十六进制。一个十进制整型字面量由一系列的数字组成,但它的第一个数字不能是0(有时十进制数字也可象下面讲的那样加后缀)。整数也可表达成八进制或十六进制形式。以0开头的整型字面量,意味着它是一个十六进制的。十六进制整数可以包括数字0-9以及字母a-f及A-F。八进制整数中则只能是出现数字0-7。在超过32位所能表示的范围之前,整型字面量的类型即为int,否则为long型。一个整型字面量可通过加后缀L或l而强迫成long型。 下面的均为合法的整型字面量。 2 2L 0777 2

7、.4.2 浮点字面量 一个浮点字面量可包括以下部分: 一个十进制整数,一个小数点“.”,小数部分(另外一个十进制整数),指数部分,一个类型后缀。指数部分是一个e或E后跟一个整数。浮点字面量至少包含有一个数字,外加或者一个小数点或者一个e(或E),下面举一些浮点字面量的例子: 3.1415 3.1E12 .1e12 2E12 就象在后面描述的那样,Java语言有两种浮点类型: float 及double,用户可按以下写法区分: 2.0d或2.0D double 型 2.0f或2.0F或2.0 float型 2.4.3 布尔字面量 布尔(boolean)字面量有两个值: true及false。 2

8、.4.4 字符字面量 字符字面量是一个由单引号括起的字符(或者是由一组字符来表述一个字符)。字符属于char类型,并且均从泛代码字符集中得来。而下面列出的转义序列则用来描述一些非图形字符,它们以反斜杠“”开始以作转义用。 续行符头 换行 NL(LF) n 垂直制表符 HT t 退格 BS b 回车 CR r 走纸换页 FF f 反斜杠 单引号 双引号 八进制数 0ddd ddd 十六进制数 0xdd xdd 泛代码字符 0xdddd udddd 2.4.5 串字面量 串字面量是双引号引起的零个或多个字符的序列。每个串字面量被看作是一个串对象,而并非是一个字符的数组,例如“abc”创建了一个新的

9、串类的实例。下面的都是合法的串字面量: 空串 只包含一个双引号的串 This is a string This is a two-line string 2.5 运算符及特殊分隔符 下面这些字符在Java源程序中作运算符或分隔符用: + ! % & * / ( ) ; ? : , = 另外,下面这些复合字符被用作运算符: + - = = != += -= *= /= &= /= = %= = = & 后面还要在运算符一节中作详细介绍。 3. 类型 任何一个变量或表达式都有一个类型,类型决定变量可能的取值范围,决定对这些值允许的操作,以及这些操作的意义是什么。Java语言中提供了内置定义类型,程

10、序员也可以利用类及界面(interface)机制构造新类型。 Java语言有两种类型: 简单类型和复合类型。简单类型指那些不能再分割的原子类型。如:整型、浮点型、布尔型、字符型均为简单类型。复合类型建立在简单类型的基础上。Java语言有三种复合类型:数组、类及界面。3.1 数值类型 3.1.1 整数类型 整数与C及C+中相似,但有两点区别: 其一,所有的整数类型均是独立于机器的;其二,对某些传统的定义作出改变,以反映自C问世以来所带来的变化,四种整数类型分别具有8位、16位、32位及64位的宽度,并且均是有符号的(signed)。如下所示: 宽度 类型名 8 byte 16 short 32

11、int 64 long 一个变量的类型不会直接影响它的存储的分配,类型仅仅决定变量的算术性质以及合法的取值范围。如果把一个超出合法范围的值赋给一变量,那么这个值将是对合法值域取模后的值。 3.1.2 浮点类型 关键字float表示单精度(32位),而double则表示双精度(64位),两个float型数运算的结果仍是float型,若有其中之一为double型,则结果为double型。3.1.3 字符类型 Java全部使用泛代码字符集,因此char类型数据被定义成一个16位的无符号整数。 3.2 布尔类型 当一个变量的取值或为ture或为false,或者是当一个方法的返回值为ture或false

12、时,它?nbsp;嵌际遣级嘈偷摹硗猓叵翟怂愕慕峁嗍遣?nbsp;尔型的。 布尔值不是数值型,因此不能用强制类型转换把它们转化成数值。 3.3 数组 数组在Java语言中属第一类对象。由它们代替了指针运算,所有的对象(包括数组)都可通过标识来引用。即使被当作数运算,标识的值也不应被破坏。通过new运算符可创建一个数组。 char s=new char30; 数组第一元素的下标为0,在声明中指定维数是不允许的。每次都必须显式地用new分配数组: int i =new int 3; Java语言不支持多维数组,但是,程序员却可以创建数组的数组。 int i =new int 34; 至少有一维要明确

13、给定,而其它维则可在以后再确定。例如: int i =new int 3 是一个合法的声明。 除了在变量名及方法名后跟方括号这种C风格的声明之外,Java语言允许方括号跟在数组类型之后,下面两行是等价的: int iarray ; int iarray; 同样地,方法声明也一样: byte f(int n) ; byte f(int n); 运行时检查下标保证它们是合法的: int a =new int 10; a5=1; a1=a0+a2; a-1=4; / 运行时引发一个ArrayIndexOutOfBoundsException(数组下标越界)异常 a10=2; /运行时引发一个Arra

14、yIndexOutOfBoundsException(数组下标越界)异常 数组的大小必须使用整数表达式: int n; float arr =new floatn+1 数组的长度可通过.length 查找: int a =new int 103; println (a.length) /打印出10 println (a0.length) /打印出3。 3.3.1 数组细节 定义的数组都是Object类的一个子类的实例,在类的层次结构中有一个被称为Array的子类,它有一个实例变量“length”。对每一个基本类型,都有一个相应的Array的子类。同理,每一个类也都有一个相应的Array子类存在

15、。例如: new Threadn 创建一个Thread 的实例。如果类A是类B的超类,那么,A是B的超类,见下图: Object Array A int float A B B 因此,可以把数组赋给一个Object变量。 Object o; int a=new int 10; o=a; 并且可通过强制类型转换把object变量赋给一数组变量。 a=(int )o; Array类本身不能显式地产生子类。 4. 类 类(class)是传统面向对象编程模型的象征。它们支持数据抽象以及实现对数据的约束,在Java中,每一个新的类创建一个新类型。要想得到一个新的类,程序员必须首先找到一个已有的类,新类即

16、在这个已有类的基础上构造,称之为派生(derived)。派生出的类亦称为原来类的子类,而这个类我们称为超类(super class)。 类的派生具有传递性: 如果B是A的子类,C是B的子类,则C 是A的子类。一个类的直接超类以及指示这个类如何实现的界面(interface),在类的声明中,由关键字extends及implements标出。如下示(黑体表示关键字): doc_ comment modifer class ClassName extends Superclassname implements interface ,interface class body 举例: /* 2 dime

17、nsion point */ public class Points float x,y; . /* printable point */ class PinttablePoint extends Points implements Printable . public void Print ( ) 所有的类均从一个根类 Object中派生出来。除Object之外的任何类都有一个直接超类。如果一个类在声明时未指明其直接超类,那么缺省即为Object。如下述: class Point float x,y 与下面写法等价 class Point extends Object float x, y;

18、 Java语言仅支持单继承,通过一个被称作“界面”的机制,来支持某些在其它语言中用多继承实现的机制(详见“界面”一节)。Java之所以没有采用C+的多继承机制,是为了避免多继承带来的诸多不便,例如:可能产生的二义性,编译器更加复杂,程序难以优化等问题。 4.1 类类型之间的强制转换 Java语言支持在两个类型之间的强制转换,因为每个类即是一个新的类型。Java支持类类型之间的强制转换,如果B是A的子类,那么B的一个实例亦可作为A的实例来使用,虽然不需要显式的转换,但显式转换亦是合法的,这被称作拓宽(widening)。如果A的一个实例,想当作B的实例使用,程序员就应写一个类型转换叫作削窄(na

19、rrowing)的强制。从一个类到其子类的强制转换在运行时要作例行的检查以确保这个对象就是其子类的一个实例(或其子类之一)。兄弟类之间的强制类型转换是一个编译错误,类的强制转换的语法如下?nbsp;?nbsp; (classname) ref 其中,(classname)是要转换的目的类,而ref是被转换的对象。强制转换仅仅影响到对象的引用,而不会影响对象本身。然而,对实例变量的访问却受到对象引用的类型的影响。一个对象从一个类型到另一类型的强制转换后,可以使同一变量名对不同的实例变量访问。 class ClassA String name = ClassA class ClassB exten

20、ds ClassA /ClassB是ClassA的子类 String name=ClassB; class AccessTest void test( ) ClassB b=new ClassB( ); println (b.name); /打印: ClassB ClassA a a=(ClassA)b; println (a.name); /打印: ClassA 4.2 方法 方法(method)是可施于对象或类上的操作,它们既可在类中,也可在界面中声明。但是他们却只能在类中实现(Java中所有用户定义的操作均用方法来实现)。 类中的方法声明按以下方式: Doc_ comment Acces

21、s Specifiers ReturnType methodName(parameterList) method body(本地的native及抽象的方法没有体部分) 除构造函数可以无返回类型外,其余的方法都有一个返回类型。如果一个不是构造函数的方法不返回任何值,那么它必须有一个void的返回类型。参数表由逗号分隔的成对的类型及参数名组成,如果方法无参数,则参数表为空。方法内部定义的变量(局部变量)不能隐藏同一方法的其它变量或参数。例如: 如果一个方法带以名为i的参数实现,且方法内又定义一个名为i的局部变量,则会产生编译错误,例如: class Rectangle void vertex (i

22、nt i,int j) for (int i=0; i=10 易引起数据丢失。 一经认定某一匹配方法是哪种转换开销,编译器则选用转换开销最小的匹配。如果有多于一个方法,其最小开销相同,则匹配有二义性,要出编译时的错误。 例如: class A int method (Object o, Thread t); int method(Thread t,Object o); void g(Object o,Thread t) method(o,t); /调用第一个方法 method(t,o); /调用第二个方法 method(t,t); /有二义性,编译出错 4.5 构造函数 构造函数(constr

23、uctor)是提供初始化的专用方法。它和类的名字相同,但没有任何返回类型。构造函数在对象创建时被自动地调用,它不能被对象显式调用。如果你想在包(package)之外调用构造函数,就将构造函数设为“public”。 构造函数也可以用不同个数和类型的参数重载,就象其它的方法被重载一样。 class Foo int x; float y; Foo() x=0; y=0.0; Foo (int a ) x=a; y=0.0; Foo (float a ) x=0; y=a; Foo (int a,float b ) x=a; y=b; static void myFoo( ) Foo obj1=new

24、 Foo( ); /调用Foo( ); Foo obj2=new Foo(4 ); /调用Foo( int a ); Foo obj3=new Foo(4.0 ); /调用Foo( float a ); Foo obj4=new Foo(4,4.0 ); /调用Foo(int a , float b); 超类的实例变量由调用超类的或当前类的构造函数初始化。如果在代码中没有指定由谁初始化,则调用的是超类中的无参数的构造函数。如果一个构造函数调用了这个类或其直接超类的另一个构造函数,这个调用必须是构造函数体的第一条语句,在调用构造函数之前实例变量不引用。 调用直接超类的构造函数如下: class

25、MyClass extends OtherClass MyClass (someParamenters ) /* 调用父类构造函数 */ super(otherParameters); 调用当前类的构造函数如下示: class MyClass extends OtherClass MyClass (someParameters) MyClass(otherParameters) /*调用当前类的构造函数,该函数有指定的参数表*/ this (someParameters); 下面的Foo和FooSub类的方法中使用构造函数的例子: class Foo extends Bar int a; Fo

26、o(int a) /隐含调用Bar( ) this.a=a; Foo( ) this (42); /调用Foo(42),代替Bar( ) class FooSub extends Foo int b; FooSub (int b) super(13); /调用Foo(13); 去掉此行将调用Foo( ) this.b=b; 4.6 用new运算符创建对象 类是用来定义对象的状态和行为的模板,对象是类的实例。类的所有实例都分配在可作无用单元回收的堆中。声明一个对象引用并不会为该对象分配存储,程序员必须显式地为对象分配存储,但不必显式删除存储,无用单元回收器会自动回收无用的内存。分配对象存储用ne

27、w运算符。除了分配存储之外,new还初始化实例变量,调用实例的构造函数。构造函数是初始化对象的一种方法(见“构 造函数”),下面的例子是分配并初始化ClassA的一个实例: a = new ClassA( ); 以下构造函数是带有参数的例子: b = new ClassA(3,2); 分配的第三种形式允许以串表达式形式提供类名字,字符串在运行时刻求值,new返回一个Object类型的对象,再转换成所希望的类型。 b = new (class+A); 这种情况下,调用构造函数时无需参数。 4.6.1 无用单元收集 无用单元收集器(Garbage Collector)使存储管理的许多方面变得简单、

28、安全。程序不需要显式释放内存,它是自动处理的。无用单元收集器不会释放正在被引用的内存,只释放那些不再被引用的空间。这就防止了悬挂指针和存储漏洞(leak)。它也使设计人员从系统的存储管理中解脱出来。 4.6.2终止 Java的构造函数完成一个对象初始化工作,Java的终止(finalization)方法则完成和析构函数类似的功能,但与C+不同之处,是它可显式调用。虽然Java的无用单元的回收功能可以自动地释放对象所占有的资源,但是对象占有的某些资源,例如: 文件描述符、套接字(socket),无用单元回收是无法处理的。所以程序员必须用终止函数来处理。诸如:关闭打开的文件,终止网络连接等程序善后工作。下面的例子是取自Java FileOutpntStream类中的终止函数。这个终止函数是一个实例的

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1