3.1 一个简单的 Java 应用程序
FirstSample
public class FirstSample { public static void main(String[] args) { System.out.println("We will ot use 'Hello, World!'"); } }
Java 区分大小写
关键字 public 称为访问修饰符(access modifier),用于控制程序的其他部分对这段代码的访问级别
关键字 class 表明 Java 程序中的全部内容都包含在类中
将类作为程序逻辑的一个容器,程序逻辑定义了应用程序的行为
类名必须以字母开头,后面可以跟字母和数字的任意组合
长度基本上没有限制
不能使用 Java 保留字作为类名
标准的命名规范为:类名是以大写字母开头的名词。如果名字由多个单词组成,每个单词的第一个字母都应该大写
骆驼命名法(camel case)
源代码的文件必须与公共类的名字相同,并用 .java 作为扩展名
在编译这段源码之后就会得到一个包含这个类字节码的文件
当使用 java ClassName 运行已经编译当程序时,Java 虚拟机总是从指定类中的 main 方法的代码开始执行,因此为了代码能够执行,在类的源文件中必须包含一个 main 方法
根据 Java 语言的规范,main 方法必须声明为 public
Java 规范:http://docs.oracle.com/javase/specs
Java 虚拟机规范:The Java® Virtual Machine Specification
Sun 公司在 Java 开源很久以前就把 bug 报告及其解决方案放在网站上让所有人监督检查,这是一种非常了不起的举动
用大括号划分程序的各个部分(通常称为块)
main 方法没有为操作系统返回“退出码”
每个句子必须用分号结束
回车不是语句的结束标志,因此,如果需要可以将一条语句写在多行上
点号(.)用于调用方法
object.method(parameters)
采用双引号界定字符串
即使一个方法没有参数,也需要使用空括号
3.2 注释
Java 中的注释也不会出现在可执行程序中
在 Java 中,有 3 种标记注释的方式。最常用的方式是使用 //,其注释内容从 // 开始到本行结尾
可以使用 /* 和 */ 注释界定符将一段比较长的注释括起来
第 3 种注释可以用来自动地生成文档。这种注释以 /** 开始,以 */ 结束
3.3 数据类型
Java 是一种强类型语言
这就意味着必须为每一个变量声明一种类型
在 Java 中,一共有 8 种基本类型(primitiv type),其中有 4 种整型、2 种浮点型、1种字符类型 char 和 1 种用于表示真值的 boolean 类型
3.3.1 整型
整型用于表示没有小数部分的数值,允许是负值
int 4 字节
short 2 字节
long 8 字节
byte 1 字节
在 Java 种,整型的范围与运行 Java 代码的机器无关
长整型数值有一个后缀 L 或 l
十六机制数值有一个前缀 0x 或 0X
八进制有一个前缀 0
从 Java 7 开始,加上前缀 0b 或 0B 就可以写二进制数
从 Java 7 开始,还可以为数字字面量加下划线,如用 1_000_000 表示 100 万
在 Java 中,所有的数值类型所占据的字节数与平台无关
Java 没有任何无符号形式的 int、long、short 或 byte 类型
Byte、Integer 和 Long 类都提供了处理无符号除法和求余数的方法
3.3.2 浮点类型
浮点类型用于表示有小数部分的数值
float 4 字节
double 8 字节
double 表示这种类型的数值是 float 类型的两倍(有人称之为双精度值)
float 类型的数值有一个后缀 F 或 f
没有后缀 F 的浮点值总是默认为 double 类型
也可以在浮点数值后面添加后缀 D 或 d
所有的浮点数值都遵循 IEEE 754 规范
下面是用于表示溢出和出错情况的三个特殊的浮点数值:
正无穷大
负无穷大
NaN(不是一个数字)
一个正整数除以 0 的结果为正无穷大。计算 0/0 或者负数的平方根结果为 NaN
常量 Double.POSITIVE_INFINITY、Double.NEGATIVE_INFINITY 和 Double.NaN 分别表示这三个特殊的值
浮点数不适用于无法接受舍入误差的金融计算,应该使用 BigDecimal 类
3.3.3 char 类型
char 类型的字面量值要用单引号括起来
char 类型的值可以表示为十六进制值,其范围从 \u0000 到 \uFFFF
3.3.4 Unicode 和 char 类型
对于任意给定的代码值,在不同的编码方案下有可能对应不同的字母
采用大字符集的语言其编码长度有可能不同
在设计 Java 时决定采用 16 位的 Unicode 字符集
现在,16 位的 char 类型已经不能满足描述所有 Unicode 字符的需要了
码点(code point)是指与一个编码表中的某个字符对应的代码值
在 Unicode 标准中,码点采用十六进制书写,并加上前缀 U+
Unicode 的码点可以分成 17 个代码平面(code plane)
第一个代码平面称为基本多语言平面(basic multilingual plane),包括码点从 U+0000 到 U+FFFF 的“经典”Unicode 代码
其余的 16 个平面的码点为从 U+10000 到 U+10FFFF,包括辅助字符(supplementary character)
UTF-16 编码采用不同长度的编码表示所有 Unicode 码点
在基本多语言平面中,每个字符用 16 位表示,通常称为代码单元(code unit);而辅助字符编码为一对连续的代码单元
在 Java 中,char 类型描述了 UTF-16 编码中的一个代码单元
强烈建议不要在程序中使用 char 类型,除非确实需要处理 UTF-16 代码单元。最好将字符串作为抽象数据类型处理。
3.3.5 boolean 类型
boolean 类型有两个值:false 和 true,用来判定逻辑条件
整型值和布尔值之间不能进行相互转换
3.4 变量与常量
3.4.1 声明变量
变量名必须是一个以字母开头并由字母或数字构成的序列
大小写敏感
不能使用 Java 保留字作为变量名
在 Java 9 中,单下划线 _ 不能作为变量名,将来的版本可能使用 _ 作为通配符
可以在一行中声明多个变量
逐一声明每一个变量可以提高程序的可读性
3.4.2 变量初始化
声明一个变量之后,必须用赋值语句对变量进行显式初始化,千万不要使用为初始化的变量值
要想对一个已经声明过的变量进行赋值,就需要将变量名放在等号左侧,再把一个适当取值的 Java 表达式放在等号的右侧
也可以将变量的声明和初始化放在同一行中
在 Java 中可以将声明放在代码中的任何地方
变量的声明尽可能地靠近变量第一次使用的地方,这是一种良好的程序编写风格
从 Java 10 开始,对于局部变量,如果可以从变量的初始化推断出它的类型,就不再需要声明类型。只需要使用关键字 var 而无须指定类型
var vacationDays = 12; // vacationDays is an int
var greeting = "Hello"; // greeting is a String
在 Java 中,并不区分变量的声明和定义
3.4.3 常量
在 Java 中,利用关键字 final 指示常量
关键字 final 表示这个变量只能被赋值一次。一旦被赋值之后,就不能再更改了。习惯上,常量名使用全大写。
在 Java 中,经常希望某个常量可以在一个类的多个方法中使用,通常将这些常量称为类常量(class constant)。可以使用关键字 static final 设置一个类常量。
如果一个常量被声明为 public,那么其他类的方法也可以使用这个常量
const 是 Java 保留的关键字,但目前并没有使用。在 Java 中,必须使用 final 定义常量
3.4.4 枚举类型
变量的取值只在一个有限的集合内
枚举类型包括有限个命名的值
enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE };
Size s = Size.SMALL;
Size 类型的变量只能存储这个类型声明中给定的某个枚举值,或者特殊值 null,null 表示这个变量没有设置任何值
3.5 运算符
3.5.1 算术运算符
算术运算符 +、-、*、/ 表示加、减、乘、除运算
当参与 / 运算当两个操作数都是整数时,表示整数除法;否则,表示浮点除法
整数的求余操作用 % 表示
整数被 0 除将会产生一个异常,而浮点数被 0 除将会得到无穷大或 NaN 结果
无论在哪个虚拟机上运行,同一运算应该得到同样当结果。对于浮点数的算术运算,实现这样的可移植性是相当困难的。double 类型使用 64 位存储一个数值,而有些h处理器则使用 80 位的浮点寄存器。这些寄存器增加了中间过程的计算精度。但是,这个结果可能与始终使用 64 位计算的结果不一样。(p38 最好读一下灰色部分)
使用 strictfp 关键字标记的方法必须使用严格的浮点计算来生成可再生的结果
public static strictfp void main(String[] args)
main 方法中的所有指令都将使用严格的浮点计算
如果将一个类标记位 strictfp,这个类中的所有方法都要使用严格的浮点计算
3.5.2 数学函数与常量
在 Math 类中,包含了各种各样的数学函数
平方根 double y = Math.sqrt(x);
幂运算 double y = Math.pow(x, a);
Math.floorMod 求余数的
常用的三角函数
Math.sin
Math.cos
Math.tan
Math.atan
Math.atan2
指数函数以及它的反函数 —— 自然对数以及 10 为底的对数:
Math.exp
Math.log
Math.log10
Java 提供了两个常量
Math.PI
Math.E
import static java.lang.Math.*;
在 Math 类中,为了达到最佳的性能,所有的方法都使用计算机浮点单元中的例程。如果得到一个完全可以预测的结果比运算速度更重要的话,那么就应该使用 strictMath 类。
Math 类提供了一些方法使整数有更好的运算安全性
3.5.3 数值类型之间的转换
当用一个二元运算符连接两个值时(例如 n + f,n 是整数,f 是浮点数),先要将两个操作数转换为同一种类型,然后再进行计算
如果两个操作数中有一个是 double 类型,另一个操作数就会转换为 double 类型
否则,如果两个操作数中有一个是 float 类型,另一个操作数就会转换为 float 类型
否则,如果两个操作数中有一个是 long 类型,另一个操作数就会转换为 long 类型
否则,两个操作数都将被转换为 int 类型
3.5.4 强制类型转换
损失信息的转换要通过强制类型转换(cast)来完成
强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,后面紧跟待转换的变量名
不要在 boolean 类型与任何数值类型之间进行强制类型转换
3.5.5 结合赋值和运算符
在赋值中使用二元运算符,这是一种很方便的简写形式
x += 4;
3.5.6 自增与自减运算符
前缀形式会先完成加 1;后缀形式会使用变量原来的值。
3.5.7 关系和 boolean 运算符
检测相等性,可以使用两个等号 ==
使用 != 检测不相等
< 小于 > 大于 = 大于等于
&& 表示逻辑“与”运算
|| 表示逻辑“或”运算
! 表示逻辑非运算
&& 和 || 运算符是按照“短路”方式来求值的:如果第一个操作数已经能够确定表达式的值,第二个操作数就不必计算了
Java 支持三元操作符 ? :
3.5.8 位运算符
可以使用掩码技术得到整数中的各个位
位运算包括:
& and
| or
^ xor
~ not
& 和 | 运算符不采用“短路”方式来求值
>> 右移
>>> 运算符会用 0 填充高位,这与 >> 不同,它会用富豪为填充高位
不存在
3.5.9 括号与运算符级别
同一个级别的运算符按照从左到右的次序进行计算(但右结合运算符除外)
《Java 核心技术卷1 基础知识》第三章 Java 的基本程序设计结构 笔记(下):https://developer.aliyun.com/article/1391463?spm=a2c6h.13148508.setting.16.74c14f0eZ4h3cS