Java 核心技术(卷一) 第三章 Java的基础程序设计结构

186 阅读10分钟

3.1 一个简单的Java应用程序

public class FirstSample 
{ 
    public static void main(string[] args)
    {
        System.out.printIn("We will not use 'Hello World!'");
    }
}
  1. Java 严格区分大小写

  2. 关键字 class 后紧跟类名

  3. 类名须遵守大驼峰命名法 

  4. 类名由单个单词组成,则单词首字母大写 

  5. 类名由多个单词组成,则每个单词的首字母都应该大写

  6. 类名须与公共类名的名字相同 

  7. 使用.java作为扩展名

  8. 根据Java 语言规范,main方法必须声明为public 

  9. 在Java 中用大括号划分程序的各个部分(通常称作为快)  

  10. 在Java 中任何方法的代码都用"{"开始"}"结束 

3.2 注释

在Java中有三种标记注释的方式

单行注释   使用//, 注释内容直到本行结尾

多行注释   以"/*"开始,以"*/"结束, 注释界定符将一段比较长的注释括起来

文档注释   以"/**"开始,以"*/"结束

/**
 * 文档注释 可以用来自动生成文档
 * @version 1.01 2020-04-28
 * @author fengtao
 */
public class FirstSample 
{ 
    public static void main(string[] args)
    {
        // 输入打印 Hello World!    ---  单行注释 
        System.out.printIn("We will not use 'Hello World!'");
        /*  此处应该有掌声 --- 多行注释 */
        /*
            多行注释
            轰隆隆...
            轰隆隆...
            轰隆隆...
        */
    }
}

3.3 数据类型

Java 是一种强类型语言, 必须为每一个变量声明一种类型

在Java 中一共有8种基本类型 (primitive type)

整型

类型    存储需求       取值范围

byte    1字节            -128 ~ 127

short   2字节            -32 768 ~ 32 767

int       4字节            -2147 483 648 ~ 2143 483 647

long    8字节            -9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807

在Java 中, 整型的范围与运行Java的机器无关. 解决软件从一个平台移植到另外一个平台, 或者软件在同一个平台中的不同操作系统之间进行移植给程序员带来的诸多问题.

由于Java程序必须保证在所有机器上都能够得到相同的运行结果, 所以各种数据类型的取值范围必须固定.

long 长整型数值有一个后缀 L或l (如4000000000L)

十六进制数值有一个前缀 0x或0X (如0XCAEF)

八进制有一个前缀0 (010对应十进制中的8) 因表示法易混淆所以不建议使用八进制常数

从Java7开始, 加上前缀0B或0b就可以写二进制数 0b1001 就是 9, 也为数字字面量加下划线 1_000_000 表示 100 万, 下划线只是为了更易读, Java 编译器会自动去除这些下划线

浮点类型

浮点类型用于表示有小数部分的数值, Java 中有两种浮点类型

类型     存储需求       取值范围

float       4 字节        大约 ±3.402 823 47E+38F (有效位数 6-7位)   

double   8 字节        大约 ±1.797 693 134 862 315 70E+308 (有效位数 15 位)

double 表示这种类型的数值精度是 float 类型的两倍 (有人称作是双精度数值)

float 类型数值有一个后缀 F 或 f (例如: 3.14F), 没有后缀 F 的浮点数值(例如: 3.14)总是默认为double 类型, 也可以在浮点数值后面添加后缀 D 或 d(例如:3.14D)

用于表示溢出和出错情况的三个特殊的浮点数值:

正无穷大

负无穷小

NaN (Not a Number 不是一个数)

例如:
一个正整数除以 0 的结果为正无穷大

    计算 0/0 或者负数的平方根结果为 NaN

常量:

    Double.POSITIVE_INFINITY

    Double.NEGATIVE_INFINITY

    Double.NaN

   (以及相应 float 类型的常量) 分别表示三个特殊的值

不能使用 if(x == Double.NaN) 来检查类型, 因为"非数值"的值都认为是不相同的

可以使用 double.isNaN(x) 来进行判断

浮点数值不适用于无法舍入误差的金融计算, 例如: System.out.printIn(2.0 - 1.1)  // 0.8999999999, 而不是人们期望的 0.9, 这种舍入误差的主要原因是浮点数值采用二进制系统表示, 而在二进制系统中无法精确的表示分数 1/10, 这就好像十进制无法精确表示分数 1/3 一样, 如果数值计算中不允许有任何的舍入误差, 就应该使用 BigDecimal 类

字符类型(char 类型)

字符类型原本用来表示单个字符, Unicode 字符可以使用一个 char 值描述, 另外一些Unicode则需要两个char值描述

char 类型的字面量需要使用单引号括起来, 'A' 是编码值为 65 的字符常量, 它与 "A" 不同, "A" 是包含一个字符 A 的字符串

char 类型的值可以表示为十六进制值, 其范围 \u0000 到\uffff 例如: \u2122 表示商标符号(TM), \u03C0 表示希腊字母π

除了转义序列\u之外, 还有一些用于表示特殊字符的转义序列, 所有的转义序列都可以出现在加引号的字符字面量或字符串中, '\u2122' 或 "Hello \n", 转义序列 \u 还可以出现再加引号的字符常量或字符串之外 (其他转义序列不可以) 例如:

public static void main(string\u005B\u005D args) ( \u005B = [     \u005D = ] ) 

特殊的字符转义序列

转义序列        名称        Unicode 值

\b                    退格        \u0008

\t                     制表        \u0009

\n                    换行         \u000a

\r                     回车         \u000d

\"                     双引号        \u0022

\'                      单引号       \u0027

\\                     反斜杠        \u005c

注意: 

转义序列会在解析代码之前得到处理, 例如 "\u0022+\u0022" 并不是一个由引号(U+0022)包围+构成的字符串, 实际上 \u0022 会在解析之前转换为 ", 这会得到一个""+"", 也就是一个空串

Unicode 编码机制

在 Unicode 之前已经有了很多不同的标准:

美国 ASCII

西欧语言中的 ISO 8859-1

俄罗斯的 KOI-8

中国的 GB18030和 big5等

这样就产生以下两个问题:

一是对于任意给定的代码值, 在不同的编码方案下有可能对应不同的字母

二是采用大字符集的语言其编码长度有可能不同, 例如有些常用的字符采用单字节编码, 而另一些字符则需要两个或多个字节

设计 Unicode 的目的就是为了要解决这些问题, 20 世纪 80 年代开始启动统一工作时, 人们认为两个字节的代码宽度足以应对世界上各种语言的所有字符编码, 并有足够的空间留给未来扩展

1991 年发布了 Unicode 1.0 当时仅占用了 65535 个代码值中不到一半的部分, 在 设计 Java 的时决定采用 16位 Unicode 字符集, 这比使用 8 位字符集的其他程序设计语言有了很大的进步

经过一段时间的发展, Unicode 字符超过了 65536 个, 其主要原因是增加了大量的汉语,日语和韩语中的表意文字,  现在 16 位的char 类型已经不能满足描述所有 Unicode 字符的需要了

Java 5 开始解决这个问题

码点 (code point) 是指与一个编码表中的某个字符对应的代码值, 在 Unicode标准中, 码点(code point) 采用 16进制书写, 并加上前缀 U+, 例如 U+0041 就表示拉丁字母 A 的码点, Unicode 的码点可以分成 17 个代码平面 (code plane), 第一个代码平面称为基本多语言平面 (basic multilingual plane), 包括码点从 U+0000 到 U+FFFF 的经典 Unicode代码, 其余的 16 个码点平面从 U+10000到 U+10FFFF, 包括辅助字符(supplementary character)

UTF16 编码采用不同长度的编码表示所有的 Unicode 码点, 在基本语言平面中, 每个字符用 16 位表示, 通常称为代码单元(code unit); 而辅助字符编码为一对连续的代码单元. 采用这种编码对表示的各个值落入基本多语言平面中未用的 2048 个值范围内, 通常称为替代区域(surrogate area) (U+D800U+DBFF) 用于第一个代码单元, U+DC00U+DFFF 用于第二个代码单元

我们可以从中迅速的知道一个代码单元是一个字符的编码, 还是一个辅助字符的第一或第二部分

布尔类型

布尔类型有两个值: false 和 true, 用来判定逻辑条件

整型数值和布尔值之间不能进行相互转换

3.4 变量与常量

3.4.1 声明变量

Java 中每一个变量都有一个类型(type), 在声明变量时, 先指定一个变量的类型, 然后是变量名

double salary;

int vacationDays;

long earthPopulation;

boolean done;

Java 语言都必须以 ; (分号) 结束

变量名必须是一个以字母开头并由字母或数字构成的序列, 大小写敏感, 长度上没有限制, 不可以使用 Java 保留字作为变量名

如果想知道那些 Unicode 字符属于 Java 中的"字母", 可以使用 Character类的 isJavaIndentifierStart 和 isJavaIndentifierPart 方法来检查

$ 是 Java 的合法字符, 但是不要在代码中使用这个字符, 他只用在 Java 编译器或其他工具生成的名字中

可以在一行中声明多个变量

int i,j;

不提倡这种风格, 逐一声明每一个变量可以提高程序的可读性

 3.4.2 变量的初始化

声明变量后, 必须用赋值语句对变量进行显示初始化

int vacationDays;

System.out.printIn(vacationDays); // ERROR -- variable not initialized

变量的声明尽可能地靠近变量第一次使用的地方, 这是一种良好的编程风格

从 Java 10 开始, 对于局部变量, 如果可以从变量的初始值推断出它的类型就不需要声明类型, 只需使用关键字 var 而无须使用指定的类型:

var vacationDays = 12; // int 

var greeting = "Hello"; // sting

3.4.3 常量

Java 中 使用关键字 final 指示常量

关键字 final 表示这个变量只能被声明一次, 一旦被赋值之后, 就不能够在更改了. 习惯上常量名使用全大写

类常量 class constant

可以使用关键字 static final 设置一个类常量

类常量定义于 main 方法的外部

如果类常量被声明成 public, 那么其他类的方法也可以使用这个常量

3.4.4 枚举

变量的取值只在一个有限的集合内

自定义枚举类型

enum Size {SMALL, MEDIUM, LARGE, EXTRA_LARGE}

声明变量

Size s = Size.MEDIUM;

Size 类型的变量只能存储这个类型生命中给定的某个枚举值, 或者特殊值 null, null 表示这个变量没有设置任何值