0%

Java核心技术卷1-Chap3-Java程序设计基本结构

本文是Java核心技术卷1-第3章-Java程序设计基本结构的读书笔记。

3.1 一个简单的Java应用程序

1
2
3
4
5
6
7
public class FirstSample
{
public static void main(String[] args)
{
System.out.println("We will not use 'Hello World'!");
}
}

这是一段最简单的Java程序,有一些值得注意的地方:

  • Java区分大小写
  • Java程序的所有内容都要包含在class
  • 关键字class后紧跟着类名,标准的类名命名规范为驼峰命名法
  • 源代码的文件名必须与公共类的类名相同(需完全一致,case-sensitive),并使用.java作为拓展名
  • 运行已编译的程序时,Java虚拟机总是从指定类中的main方法处开始执行。因此类的源文件中必须包含一个main方法
  • Java中的main方法必须是静态static

注意:根据Java语规范,main方法必须声明成public。

3.2 注释

Java中的注释有三种:

  • 使用//,注释范围到行尾;
  • 使用/**/来界定注释;
  • /**开始,以*/结束,这种注释方法可用来自动生成文档。

警告:Java中/**/不能嵌套,也就是说不能直接将代码用/**/括起来注释,因为中间可能还会碰到*/界定符。

3.3 数据类型

Java是一种强类型语言。因此必须为每一种变量声明一种类型。在Java中一共有8种基本类型(primitive type):4种整形、2种浮点型、1种字符型char、1种布尔类型boolean

注意:Java种还有一种能表示任意精度的算术包,通常称为“大数”,但它不是一种Java基本类型,而是一个Java对象。

3.3.1 整型

Java种的整型有:intshortlongbyte,均允许有负数。注意:Java种没有任何无符号形式的intshortlongbyte类型。

Java种整型的范围和所占存储空间与平台无关,因此能保证在任何机器上都得到相同的运行结果。

整型数值的表示:

  • 长整型数值后有一个后缀L或者l,如40000000000L
  • 十六进制数值后有一个前缀0x或者0X
  • 八进制数值前有一个0
  • 从Java7开始,加上0b或者0B前缀就可以写二进制数,如0b1001就是9,数字字面量可以加下划线让人更易读,编译器实际上会去掉这些下划线,如1_000_000

3.3.2 浮点类型

Java种的浮点类型有floatdoublefloat有效位数是67位,double有效位数是1516位。

浮点类型的表示:

  • float类型后有一个后缀Ff(例如3.14F
  • 没有后缀的浮点数值默认为double,当然,也可以在后面添加Dd后缀。

注释:还可以用十六进制表示浮点数值,例如0.125=2^-3可以表示成0x1.0p-3,十六进制表示法种p表示指数而不是e,尾数采用十六进制,而指数采用十进制,而且指数的基数是2而不是10

所有的浮点数值计算都遵循IEEE 754规范。下面是用于表示溢出或出错情况的三个特殊的浮点数值:

  • Double.POSITIVE_INFINITY,正无穷大
  • Double.NEGATIVE_INFINITY,负无穷大
  • Double.NaN,不是一个数字

注意:所有的“非数值”的值都认为是不同的,不能直接比较(如x==Double.NaN),但可以使用内置的方法来比较(Double.isNaN(x))。

3.3.3 char类型

char类型原本用于表示单个字符,但如今有些Unicode字符也可以用一个char值来描述,另外一些Unicode字符则需要两个字符。

char类型的字面值常量需要用单引号括起来。char类型的值可以表示为十六进制值,范围从\u0000\uFFFF

3.3.4 Unicode与char类型

3.3.5 boolean类型

boolean类型有两个值:falsetrue,注意:Java中整数值和布尔值之间不能进行相互转换

3.4 变量与常量

3.4.1 声明变量

Java中每个变量都有一个类型,在声明变量时,首先指定变量的类型,然后再指定变量名:

1
2
double salary;
boolean done;

变量命名的规则:…

可以在一行中声明多个变量,但不建议这样做,逐一声明可以提高程序的可读性。

3.4.2 变量初始化

声明一个变量后必须用赋值语句对变量进行显示初始化。不能够使用未初始化的变量的值。Java不区分变量的声明和定义。

1
2
3
4
int vacationDays;
vacationDays = 12;
// or
int vacationDays = 12;

在Java程序编写风格中,变量的声明应接近第一次使用的地方。

从Java10开始,对于局部变量,如果可以从变量的初始值推导它的类型,就可以使用关键字var而不指定声明类型:

1
var greeting = "Hello"; // greeting is a String

3.4.3 常量

Java中使用关键字final来表示常量。习惯上,常量名采用全大写。

1
final double CM_PER_INCH = 2.54;

3.4.4 枚举类型

有时变量的值只会是在某一取值集合内,比如衣服的尺寸有S、M、L、X。如果想让变量只在这个集合内取值,而不能保存其他错误的值,可以自定义枚举类型

1
2
enum Size {SMALL, MEDIUM, LARGE, EXTRA_LARGE};
Size s = Size.MEDIUM;

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

3.5 运算符

3.5.1 算数运算符

算数运算符有+-*/%,分别表示加、减、乘、除、取余(求模)。

注意:浮点数运算的可移植性实现起来很难,例如:double类型使用64位存储一个数值,而有些处理器使用80位的浮点寄存器,这些寄存器增加了中间过程的计算精度,而且避免了指数溢出,但这个结果可能与64位计算的结果不一样。如果要使用严格的浮点计算来生成可再生的结果,可以把方法或类标记成strictfp

1
public static strictfp void main(String[] args)

3.5.2 数学函数与常量

Math类中包含各种各样的数学函数。

方法 操作
Math.sqrt(x) 计算x的平方根
Math.pow(x, a) 计算x的a次幂
Math.floorMod(x)

3.5.3 数值类型之间的转换

3.5.4 强制类型转换

3.5.5 结合赋值和运算符

3.5.6 自增和自减运算符

3.5.7 关系和boolean运算符

3.5.8 位运算符

3.5.9 括号和运算符级别

3.6 字符串

3.8 控制流程

Java中使用条件语句、循环结构来确定控制流程。

3.8.1 块作用域

块(即复合语句)是指由若干条Java语句组成的语句,并用一对大括号括起来。块确定了变量的作用域,块可以嵌套。

注意:不能在嵌套块中声明同名的变量。(但在C++中可以,内层同名变量隐藏外层变量)

3.8.2 条件语句

Java中条件语句的格式为

1
if (condition) statement1 else statement2

statement常采用块(复合语句)。

3.8.3 循环语句

当条件为true时,while循环执行:

1
while (condition) statement

在上面的这种while语句中,statement可能一次都不执行。为了保证statement至少执行一次,可以使用**do/while循环**。语法如下:

1
do statement while (condition)

for循环是支持迭代的一种通用结构,由一个计数器或者类似的变量控制迭代次数,每次迭代后计数器更新。

1
2
for (int i = 1; i <= 10; i++)
statement;

注意:检测浮点数是否相等时需要额外注意,因为会有舍入误差。

多重选择:**switch语句**,Java中的switch语句和C++中的完全一样。其语法如下:

1
2
3
4
5
6
7
8
9
switch (choice)
{
case 1:
break;
case 2:
break;
default:
break;
}

case标签可以是:

  • 类型为charbyteshortint的常量表达式
  • 枚举常量
  • 从Java7开始,case标签还可以是字符串字面量

例如:

1
2
3
4
5
6
7
String input = ...;
switch (input.toLowerCase())
{
case "yes":
break;
...
}

中断控制流程有**break语句Continue语句**。Java中提供了两种break语句,一种与C++中的一致,另一种是带标签的break语句。

1
2
3
4
label:
{
if (condition) break label;
}

注意:标签必须放在希望跳出的最外层循环之前,且必须紧跟一个冒号。

同样的,continue语句也有带标签和不带标签两种形式。

3.9 大数

java.math包中有两个很有用的类:BigIntegerBigDecimal。这两个类可以处理包含任意长度字符序列的数值。BigInteger用于实现任意精度的整数运算,BigDecimal用于实现任意精度的浮点数运算。例如在金融货币方面就非常有必要。

使用静态的valueOf方法可以将普通的数值转换为大数:

1
BigInteger a = BigInteger.valueOf(100);

对于更大的数,可以采用一个带字符串的参数构造器:

1
BigInteger reallyBig = new BigInteger("22222222342342347238563278562374526312847198547825");

另外大数类中也定义了一些常量:BigInteger.ZEROBigInteger.TENBigInteger.ONEBigInteger.TWO

注意:不能用常用的算术运算符处理大数,而需要使用大数类中的addmultiply方法。

1
2
BigInteger c = a.add(b); // c = a + b
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2))) // d = c * (b + 2)

更多的大数操作可以见:http://c.biancheng.net/view/871.html

3.10 数组

Java中的数组声明如下:

1
2
3
4
5
6
7
8
int[] a; // 数组的声明
int[] a = new int[100]; // 声明并初始化可存储100个整数的数组
var b = new int[100];
for(int i = 0; i < a.length; i++) {
System.out.println(a[i]);
a[i] = i;
System.out.println(a[i]);
}

Java中的