Core-Java 阅读笔记 -2
2021-04-24 22:43:59 # Java

前言:这是Core-Java中的第三章部分Java的基本程序设计结构

一.程序基本结构

1.1 Java程序基本结构

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

这个程序虽然简单,但是所有Java程序都应该是具有这样的结构

public成为访问修饰符,用来控制程序其他部分对这段代码的访问级别;

class后跟类名,名字必须以字母开头,可以跟字母+数字任意组合,长度没有限制,不能使用保留字,类名是以大写字母开头的名词,如果由多个单词组成,每个单词的第一个字母应该大写,源文件的文件名必须和公共类名一致

运行到已编译的程序,JVM总是从main方法开始执行,根据Java语言规定,main方法必须为public,从Java1.4以后强制main方法必须为public

源码中的大括号{}用于划分程序的各个部分,通常称为块,

在这里我们使用了System.out对象并且调用了println方法,'.'表示方法调用

java中通用的语法是

object.method(parameters)

1.2 注释

// 单行注释

/**/ 多行注释

/** */ 文档注释

1.3 数据类型

Java是一种强类型语言,所以必须为每一个变量声明一个类型,在Java中,一共有8种基本类型(primitive type),其中有4种整数,2种浮点数,1种字符类型(char)和1种表示真值的boolean类型

1.3.1 整数

整数即没有小数的数值

类型 存储需求 取值范围
int 4字节 -2 147 483 648 ~ 2 147 483 647(刚刚过20亿)
short 2字节 -32 768 ~ 32767
long 8字节 -9 233 372 036 854 775 808 ~ 9 233 372 036 854 775 807
byte 1字节 -128 ~ 127
  1. 在Java中,由于整数范围与机器无关,这就解决了软件跨平台的问题;

  2. 在长整形中有一个后缀l或者L;

  3. 十六进制数前缀为0x或0X,八进制数哟一个前缀0;

  4. 从Java7开始,加上0b或0B就可以表示为二进制数,还可以为数字字面量加上下划线表示二进制,

如1_000_000(或0b1111_0100_0010_0100_0000)表示100万,这些下划线只是方便阅读,在编译期会自动去除;

  1. Java中没有无符号数(unsigned)形式的int,long,short或byte类型;

1.3.2 浮点数

表示有小数部分的数值

类型 存储需求 取值范围
float 4字节 大约 ± 3.402 823 47E+38F(有效位数为6 ~ 7位)
double 8字节 大约 ± 1.797 693 134 862 315 70E+308(有效位数为15位)
  1. 在很多情况下,float不能满足需求,大量使用的是double类型;

  2. float类型需要在后面加上后缀F或f,没有加上的浮点数会被默认识别为double类型,也可以在浮点数后面加上D或者d;

  3. 常量Double.POSITIVE_INFINITY,Double.NEGATIVE_INFINITYDouble.NaN分别可以用来表示正无穷大,负无穷大和不是一个数字,但是不能检测一个特定的值是否等于Double.NaN,但是可以使用Double.isNaN方法来判断;

1
2
3
4
5
6
7
8
if(x == Double.NaN){
//所有的"非数值"的值都认为是不相同的,但可以使用Double.isNaN()方法
doSomething...;
}

if(Double.isNaN(x)){
doSomething...;
}

(4). 浮点数不适用于无法接受舍入误差的金融计算,原因在于计算机无法表示出所有的二进制浮点类型,如果不希望有舍入误差,应该使用BigDecimal类;

1.3.3 char

  1. 原用来表示单个字符,现有些Unicode字符可以使用一个char值来表示,另外有一部Unicode字符则使用2个char表示;

  2. char类型的字面量需要使用单引号括起来,也可以表示十六进制值,其范围包括000到

1.3.4 Unicode

Unicode是一种新的编码机制,打破了传统英文字符编码机制的限制,在Unicode出现之前,有没过的ASCII,西欧语言的ISO 8859-1,俄罗斯的KOI-8, 中国的GB 18030和 BIG-5等,但是对于一个给定长度的代码值,在不同编码方案中可能对应着不同的字符.而且采用大字符集的语言编码长度有可能不同,有些常用的字符集采用单字节,有些则使用两个或者多字节.

设计Unicode编码就是为了解决这些问题.最早人们认为两个字节的代码宽度足以对世界上所有语言的字符进行编码,Java在设计之初就考虑到8位字符集可能不够,使用了16位的字符串,但是目前16位char也不能满足所有Unicode字符;

在Java中,char类型描述了UTF-16编码中的一个代码单元;

强烈建议不要在程序中使用char类型,除非确实需要处理UTF16代码单元,最好将字符串作为抽象数据类型处理

1.3.5 boolean

用来判断逻辑条件,整数与布尔值不能互相转换

1.4 变量与常量

1.4.1 声明变量

每个变量都有一个类型(type),在声明前,都要指定类型,然后再是变量名;

不能使用Java中的保留字或者关键字作为变量名;

1.4.2 变量初始化

声明后必须进行显式初始化, 不能使用没有被初始化的值,将会在编译期就报错;

1.4.3 常量

使用 final 关键字声明常量,声明后,这个变量只被赋值一次,且后面不能再修改;

在Java中,如果希望一个常量在一个类的多个方法中使用,常常需要设置为类常量,使用 static final修饰

1.4.4 枚举

有时,变量的取值只在一个有限的集合中,所以可以自定义枚举类型,

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

1.5 运算符

用于连接值

1.5.1 算术

+ ,- ,*,/表示数字加减乘除运算

  1. 参与 / 运算只有有浮点数参数才为浮点数运算,否则为整数运算;
  2. 整数才有求余操作

对于浮点数调度可移植性计算是十分困难的,double类型使用64位存储一个数字,但是有些处理器使用80位的浮点寄存器,这些寄存器增加了中间过程的计算精度.

如计算 double w = x * y / z;

很多Inter处理器计算x * y,并且将结果存储在80位的寄存器中, 在除以z并将结果截断为64位,这样可以得到一个更加精确的结果,并且能够避免产生指数溢出.但是这个结果可能很始终使用64位计算的结果不一样.因此,JVM最初规范所有的计算都必须进行截断,但是遭到了数字社区的反对,截断计算不仅可能导致溢出,而且由于截断操作也需要消耗时间,所以在计算速度上实际上也是要比精确计算更慢,为此,Java承认了最优性能与理想的可再生性之间存在的冲突,并且给予了改进,在默认情况下,现代JVM设计者允许对中间计算采用扩展的精度,但是,如果是使用了strictfp关键字标记的方法必须使用严格的浮点数计算来生成可再生的结果

例如,如果把main方法标记为

public static strictfp void main(String[] args) {}

那么,main方法中所有的计算都必须使用严格的浮点计算

这其中具体的计算细节取决于Inter处理器的行为,在默认情况下,中间结果允许使用扩展的指数,但是不允许使用使用扩展的尾数(Inter芯片支持截断尾数时并不损失性能).因此,此时这两种方式的区别仅仅是,采用默认方式不会产生溢出,但是采用严格计算则可能会产生溢出

1.5.2 数学函数

在Math类中,包含了各种数学函数

如果不想再所有数学方法和变量名前都加上前缀"Math",只要在源文件顶部使用"静态导入"即可

import static java.lang.Math.*;

1.5.3 数值之间的转换

image-20210513110305743

实线代表无精度丢失转换,虚线代表有可能会有精度丢失的转换;

当使用一个二元操作符(+)操作时,会先把两个操作数转换为同一种类型(以两者中大的为准),再进行运算

1.5.4 强制类型转换

在圆括号中给出想要转换的目标类型即可

1.5.5 结合赋值

+= ,-=,*=,/=

1.5.6 自增/自减

++,--

1.5.7关系和boolean

==,>,< >=,>=,!=,&&,||,condition ? expression1 : expression2

1.5.8 位运算

&(and),|(or),^(xor),~(not)

1.6 字符串

即Unicode字符序列,Java没有内置字符串类型,而是在Java标准类库中提供了一个预定义类,所有用双引号括起来的字符串都是String类的示例

1.6.1 子串

substring方法可以从一个较大的字符串中提取出一个子串

1.6.2 拼接

  1. 允许使用+号连接两个字符串

  2. 如果是字符串与非字符串拼接,则回先转为字符串在拼接

  3. 如果需要把多个字符串放在一起,用界定符分隔,则需要使用静态join方法

  4. 在Java11中,还提供了repeat方法

1.6.3 不可变

String类本身没有提供修改字符串某个字符的方法,由于不可以修改字符串中的单个字符,所以在Java中String类被称为是不可变的(immutable)

1.6.4 检测字符串是否相等

  1. 可以使用equals方法检测两个字符串是否相等;
  2. 如需要不区分大小写,可以使用equalsIgnoreCase方法;
  3. 不可以使用==判断字符串是否相等,只可以用来检测是否为同一块内存地址的引用;

1.6.5 空串和null

空串为长度为0的字符串

null是一个空引用

1.7 输入与输出

1.7.1 读取输入

如果需要输出,只需要调用标准输出流System.out即可

输入则需要调用标准输入流System.in,要通过控制台输入,需要构建标准输入流的Scanner对象

Scanner in = new Scanner(System.in);

1.7.2 格式化输出

可以使用System.out.printf()进行格式化输出,语法同C/C++

1.8 控制流程

1.8.1 块作用域

使用一对大括号括起来的若干条语句

1.8.2 条件语句

if(condition) statement

1.8.3 循环

while();

do... while()

for(;;)

1.9 大数

包括BigInterger和BigDecimal

相关方法可查阅API

1.10 数组

for each结果(Java5新引入)

for(variable : collection) statement