Java语言规范(Java SE 22)章1 引言

        Java是一种通用的、并发的、基于类的面向对象的编程语言。它的设计理念就是足够简单,让程序员可以轻松掌握这门语言,它和C、C++存有关联的,但设计上又有很大差异,它抛弃了C和C++很多方面的内容并借鉴了其他语言的一些想法。Java旨在成为一种面向生产的语言,而不是为学术研究,正如C.A.R.Hoare在它的语言设计论文中建议的那样,Java避免引入一些新的未经过测试的特性。

        Java是强类型静态语言,这篇语言规范把编译期间可以检测到的编译时错误和运行时错误明确区分开来。编译是把程序转换成与机器无关的字节码表示的过程,而运行时通常会包括运行一个程序所需要的类的加载和链接以及可能存在的机器码的生成和程序的动态优化并真正执行程序。

        Java语言是一种高级编程语言,机器表示的细节无法通过该语言获得,它包含自动内存管理,采用垃圾回收器避免了显式内存申请和释放存在的安全性问题(如C中的free和C++中的delete)。高性能的垃圾回收实现,足以支撑系统编程和实时应用场景。Java并没有包含不安全的构件,比如未经索引检查的数组访问,这些不安全的构件可能会导致程序以不明确的方式运行。

        Java语言通常会编译成字节码,其二进制形式在Java虚拟机规范中进行描述。

1.1 该规范组织形式

        第 2 章描述了语法和用于表示语言词汇和句法语法的符号。

        第3章描述了基于C和C++的Java编程语言的词法结构。该语言是用 Unicode 字符集编写的。它支持在仅支持 ASCII 的系统上写入 Unicode 字符。

        第 4 章介绍了类型、值和变量。类型细分为基本类型和引用类型。

        基本类型在所有计算机和所有实现中定义为相同,并且是各种大小的二进制补码整数、IEEE 754 浮点数、布尔类型和 Unicode 字符字符类型。基本类型的值不共享状态。

        引用类型包括类类型、接口类型和数组类型。引用类型由动态创建的对象实现,这些对象可以是类的实例,也可以是数组的实例。可以存在对每个对象的多个引用。所有对象(包括数组)都支持类 Object 的方法,Object 是类层次结构的(单个)根。预定义的 String 类支持 Unicode 字符串。存在用于将基元值包装在对象内部的类。在许多情况下,换行和解包由编译器自动执行(在这种情况下,换行称为装箱,解包称为拆箱)。类和接口可以是泛型的,也就是说,它们可以按引用类型进行参数化。然后,可以使用特定的类型参数调用此类和接口的参数化类型。

        变量是类型化的存储位置。基本类型的变量包含该确切基本类型的值。类类型的变量可以保存空引用或对对象的引用,该对象是命名类的实例或该类的任何子类。接口类型的变量可以保存 null 引用或对实现命名接口的任何类的实例的引用。数组类型的变量可以保存 null 引用或对数组的引用。类类型为 Object 的变量可以保存 null 引用或对任何对象的引用,无论是类实例还是数组。

        第 5 章介绍了类型转换和数值类型提升。类型转换会更改编译时类型,有时还会更改表达式的值。这些转换包括基本类型和引用类型之间的装箱和拆箱操作。数值提升用于将数值运算符的操作数转换为可以执行某操作的通用类型。该语言没有漏洞;在运行时会对类型的强制转换做检查,以确保类型安全。

        第 6 章介绍了声明和名称,以及如何确定名称的含义(即名称表示哪个声明)。Java 编程语言不要求在使用类和接口或其成员之前声明它们。声明顺序仅对局部变量、局部类、局部接口以及类或接口中的字段初始化的顺序具有重要意义。此处介绍了使程序更具可读性的推荐命名约定。

        第 7 章描述了程序的结构,该程序被组织成包。包的成员包括类、接口和子包。包及其成员的名称均在具有层次结构的名称空间中定义;互联网域名系统通常可以用来形成唯一的包名。编译单元包含作为给定包成员的类和接口的声明,并且可以从其他包导入类和接口以赋予它们短名称。

        包可以分组到模块中,这些模块在构建非常大的程序时充当构建块。模块的声明指定了在自己的包中编译和运行代码所需的其他模块(以及包、类和接口)。

        Java 编程语言支持对包、类和接口成员的外部访问限制。包的成员只能由同一包中的其他成员访问,也可以由同一模块的其他包中的成员访问,也可以由不同模块中的包的成员访问。类似的约束也适用于类和接口的成员。

        第 8 章介绍类。类的成员是类、接口、字段(变量)和方法。每个类存在一次类变量。类方法在不引用特定对象的情况下运行。实例变量是在作为类实例的对象中动态创建的。实例方法在类的实例上调用;这样的实例在执行过程中成为当前对象(this),支持面向对象的编程风格。

        类支持单继承,其中每个类都只有一个超类。每个类都继承其超类的成员,并最终继承类 Object 的成员。类类型的变量可以引用命名类的实例或该类的任何子类,从而允许以多态方式将新类与现有方法一起使用。

        类支持使用synchronized方法进行并发编程。方法声明其执行中可能产生的检查类异常,这允许编译时检查以确保处理异常情况。对象可以声明一个 finalize 方法,该方法将在垃圾回收器丢弃对象之前调用,从而允许对象清理其状态。

        为简单起见,该语言既没有独立于类实现的声明“标头”(headers),也没有单独的类型和类层次结构。

        一种受限制的类,即枚举类,支持以类型安全的方式定义小值集及其操作。与其他语言中的枚举不同,枚举常量是对象,可能有自己的方法。

        另一种受限制的类,即记录类,支持作为值聚合的简单对象的紧凑表达式。

        第 9 章介绍了接口。接口的成员包括类、接口、常量字段和方法。不相关的类可以实现相同的接口。接口类型的变量可以包含对实现接口的任何对象的引用。    

        类和接口支持从接口进行多次继承。实现一个或多个接口的类可以从其超类和超接口继承实例方法。

        注解是元数据,可以应用于程序中的声明,以及声明和表达式中类型的使用。注解的形式由注解接口定义,注解接口是一种特殊的接口。注解不允许以任何方式影响 Java 编程语言中程序的语义。但是,它们为各种工具提供了有用的输入。

        第 10 章介绍数组。数组访问包括边界检查。数组是动态创建的对象,可以分配给 Object 类型的变量。该语言支持数组的数组,而不是多维数组。

        第 11 章描述了异常,这些异常是不可恢复的,并且与语言语义和并发机制完全集成。有三种类型的异常:已检查异常、运行时异常和错误。编译器要求方法或构造函数必须处理所有已检查类异常,否则必须在方法或构造函数处声明。这提供了编译时检查是否存在异常处理程序,并有助于大型编程。大多数用户定义的异常都应为检测类异常。Java 虚拟机检测到的程序中的无效操作会导致运行时异常,例如 NullPointerException。错误是由 Java 虚拟机检测到的故障(如 OutOfMemoryError)导致的。大多数简单的程序不会尝试处理错误。

        第 12 章描述了在程序执行期间发生的活动。程序通常存储为表示已编译类和接口的二进制文件。这些二进制文件可以加载到 Java 虚拟机中,链接到其他类和接口,并进行初始化。

        初始化后,可以使用类方法和类变量。某些类可能会被实例化以创建类类型的新对象。作为类实例的对象还包含类的每个超类的实例,并且对象创建涉及这些超类实例的递归创建。

        当对象不再被引用时,垃圾回收器可能会回收该对象。如果对象声明了终结器,则在回收对象之前执行终结器(finalizer),以便为对象提供清理原本不会释放的资源的最后机会。当不再需要某个类时,它可能会被卸载。

        第 13 章介绍了二进制兼容性,指定了对类和接口的更改对使用更改后的类和接口但尚未重新编译的其他类和接口的影响。这些注意事项对于类和接口的开发人员来说很有意义,这些类和接口将在一系列连续的版本中广泛分发,通常是通过 Internet 分发的。好的程序开发环境会在类或接口发生更改时自动重新编译依赖代码,因此大多数程序员无需担心这些细节。

        第 14 章介绍了块和语句,其是基于 C 和 C++ 的。该语言没有 goto 语句,但包含标记的 break 和 continue 语句。与 C 不同,Java 编程语言在控制流语句中需要布尔(或布尔)表达式,并且不会隐式地将类型转换为布尔值(除非通过拆箱操作),以期在编译时捕获更多错误。synchronized 语句提供基本的对象级监视器锁定。try 语句可以包括 catch 和 finally 子句,以防止非本地控制转移。第 14 章还介绍了模式,这些模式在语句(和表达式)中用于有条件地声明和初始化局部变量。

        第 15 章介绍了表达式。本文档完全指定了表达式的(明显)计算顺序,以提高确定性和可移植性。重载的方法和构造函数在编译时通过从适用的方法或构造函数中选取最具体的方法或构造函数来解析。

        第 16 章描述了该语言确保在使用前明确设置局部变量的精确方式。虽然所有其他变量都会自动初始化为默认值,但 Java 编程语言不会自动初始化局部变量以避免屏蔽编程错误。

        第 17 章介绍了线程和锁的语义,它们基于最初在 Mesa 编程语言中引入的基于监视器的并发。Java 编程语言为支持高性能实现的内存共享多处理器的内存模型。        

        第 18 章介绍了各种类型推断算法,这些算法用于测试泛型方法的适用性和在泛型方法调用中推断类型。

        第19章介绍了该语言的句法语法。

1.2 示例程序

 文中给出的大多数示例程序都是可以直接执行的,并且在形式上类似于:

class Test {
     public static void main(String[] args) {
        for (int i = 0; i < args.length; i++)
            System.out.print(i == 0 ? args[i] : " " + args[i]);
        System.out.println();
     }
}

在安装了 Oracle JDK 的计算机上,可以通过提供以下命令来编译和执行存储在文件Test.java中的此类:

javac Test.java
java Test Hello, world.

输出如下:

Hello, world.

1.3 标记

        在本规范中,我们会引用 Java SE 平台 API 中提取的类和接口。每当我们使用单个标识符 N 引用类或接口(示例中声明的类或接口除外)时,预期的引用是包 java.lang 中名为 N 的类或接口。我们使用规范名称 (§6.7) 来表示来自 java.lang 以外的软件包的类或接口。

        本规范中的交叉引用显示为 (§x.y)。有时,我们通过以下形式的交叉引用来引用 Java 虚拟机规范,Java SE 22 Edition 中的概念。

        非规范性文本旨在澄清本规范的规范性文本,以如下形式给出。

                   这是非规范性文本。它提供直觉、理由、建议、示例等。

        为了缩短对某些规则的描述,特别是那些系统地分析Java编程语言结构的规则,习惯缩写“iff”用于表示“当且仅当”。 

        Java 编程语言的类型系统有时依赖于替换的概念。符号 [F1 :=T1,...,Fn :=Tn ] 表示对于1 ≤ i ≤ n用 Ti 代替Fi 。

1.4 预定义类和接口的关系

        如上所述,该规范通常引用 Java SE 平台 API 的类和接口。特别是,一些类和接口与Java编程语言有着特殊的关系。示例包括 Object、Class、ClassLoader、String 和 Thread 等类,以及包 java.lang.reflect 中的类和接口等。该规范限制了此类和接口的行为,但没有为它们提供完整的规范。读者可以参考Java SE Platform API 文档。

        因此,本规范没有详细描述反射。许多语言结构在核心反射 API (java.lang.reflect) 和语言模型 API (javax.lang.model) 中都有类似的结构,但这里通常不讨论这些结构。例如,当我们列出创建对象的方式时,我们通常不包括 Core Reflection API 完成此操作的方式。即使文中没有提及,读者也应该了解这些附加机制。        

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值