《Java深入解析-透析Java本质的36个话题》笔记_第一章

# 《Java深入解析》透析Java本质的36个话题笔记

 

## 第1 章 基本概念1

### 话题1 开门见山——测试你的Java 水平 1

### 话题2 世外隐者——隐居深山的“关键字” 2

goto const是java中的关键字,不允许作为标识符使用

true,false,null 不是关键字,也不能用于标识符,是字面常量。

 

### 话题3 疑团满腹——标识符更深层的思考6

(1)标识符的定义常见规则:

重新定义:

使用Character的方法可以判断一个字符可不可以作为标识符使用

 

```java

private static void valid() {

 int startNum = 0;

 int partNum = 0;

 for(int i=0x0000;i<0x10ffff;i++) {

  if(Character.isJavaIdentifierStart(i)) {

   startNum++;

  }

  if(Character.isJavaIdentifierPart(i)) {

   partNum++;

  }

 }

 System.out.println("Unicode字符集个数:"+(0x10ffff+1));

 System.out.println("可以作为标识符首的字符个数:"+startNum);

 System.out.println("可以作为标识符一部分的字符个数:"+startNum);

 System.out.println("差:"+(partNum-startNum));

}

输出:

Unicode字符集个数:1114112

可以作为标识符首的字符个数:101296

可以作为标识符一部分的字符个数:101296

差:2288

```

 

Unicode字符集范围0x0000-0x10ffff

标识符的字母不局限26个字母,包含了其他的Unicode字符,但只是Unicode字符集的一部分,

不能作为标识符首的字母也不只限0-9数字字符

 

(2)避免$符号命名标识符

避免使用$符号命名标识符,会出现意想不到的错误,$符号通常用于编译器生成的文件命名,可以查看class文件。

 

(3)标识符长度

java语言规范中标识符长度是任意的,但在Java虚拟机规范中是有长度限制的。在class文件中,标识符常量字符串存储在CONSTANT_Utf8_info表中,使用2个字节表示字符串长度,最大长度为65535(2^16-1),所以标识符最大长度也是65535,而且仅限于除了空字符null以外的ASCII字符(‘\u0001’-‘\u007f’),使用这个范围以外的字符,最大长度会减少。

 

### 话题4 鞭长莫及——我的特殊字符,你不能用!10

(1)三种转义

下面的定义会报错

```java

char c1 = '\u0027'; //转义之后为单引号,没有合理的匹配

char c2 = '\u005c'; 转义之后为\,转义符后面要跟转义的字符

String string = "\u0022"; //转义之后为双引号,没有合理的匹配

char c3 = '\400'; // 八进制转义范围:0-255('\u0000'-'\u00ff'),'\400'的十进制表示256

char c4 = '\28'; // 八进制转义只能有0-7数字

```

 

(2) 回车换行不要使用Unicode转义

```java

char c4 = '\u000a';// 转义为换行

相当于在'后面键入换行符

char c4 = '

';

 

char c4 = '\u000b';// 转义为回车

相当于在'后面键入回车

char c4 = '

';

 

// 使用下面两种方式表示回车换行

char c1 = '\n';// 换行

char c2 = '\12';// 换行

char c3 = '\r';// 回车

char c4 = '\15';// 回车

```

 

(3)区别和联系

Unicode转义在编译器丢弃空白和注释之前就进行转换成其表示的字符,转义序列符和八进制转义的处理要晚。

(4)Unicode增补字符:超出原来的16位限制的字符

U+0000~U+10FFFF 为基本多语言面(BMP)

0x10000-0x10FFFF 为增补字符范围,增补字符使用两个代码单元(一个字符编码使用的最小存储单元)来编码,不能使用char类型常量表示,超出了65535范围。

如:\u10000 要表示为\ud800\udc00

第一个代码单元高代理范围(U+D800~U+DBFF),低代理范围(U+DC00~U+DFFF)

增补字符代理对的值区间为U+D800~U+DFFF,该区间没分配字符。

 

### 话题5 移星换斗——从byte b = 1 谈类型转换的神秘 16

(1)隐式转换

```java

private void int2Byte() {

 // 这是特例,隐式转换

 // (1)只使用于对变量类型是byte,short或char赋值的时候

 // (2)赋值安全。对超过范围的转换会报错。

 byte b = 1;

 char c = 1;

 short s = 1;

 int i = 1;

 // 下面的会报错

// byte b2 = i;

// char c2 = i;

// short s2 = i;

}

```

(2)整形转换

整形:byte,short,char,int,long

char无符号(0~65535),转byte和short都要显式类型转换。

byte,short,char运算结果为int类型。

“+=” 复合运算在赋值时会自动转换结果为左边操作数类型。

byte 转char 要扩展收缩转换:先byte类型扩展转int类型,再从int收缩成char类型。

 

如:byte值为10,补码

0000 1010

扩展为int类型,补码:

0000 0000 0000 0000 0000 0000 0000 1010

int收缩为char类型,补码:

0000 0000 0000 1010

结果还是10

 

byte值为-10,补码

1111 1010

扩展为int类型,补码:

1111 1111 1111 1111 1111 1111 1111 1010

int收缩为char类型,截取低16位,补码:

1111 1111 1111 1010

结果就不是10

 

整形之间的转换,有符号符号位扩展,无符号0扩展。大转小截断。

 

(3)整形转浮点

所有整形转浮点都是扩展转换,但跟整形之间的扩展转换不同,整形之间的扩展转换是精确的。

 

### 话题6 扑朔迷离——浮点类型的种种悬疑22

(1)避免浮点数比较

二进制能表示的相邻的浮点值之间存在间隙。

浮点值越大,间隙越大,跟存储方式有关。

当浮点值大到一定程度,对浮点值改变很小,不足以影响浮点值改变。

浮点数量级差别很大时,做加减运算可能无法得到预期的结果。

 

(2)整形转浮点

当int类型或long类型数值的有效数字多于float或double类型最大有效数字,一些最低有效位就会丢失。

丢失精度采用IEEE754最近舍入算法

 

(3)浮点转整形

NaN -> int,long 类型为0

+-Infinity(正负无穷) 或超过int或long取值范围,结果为int或long最大值

在int或long取值范围,向0取整

转byte,short,char,先转int再收缩

 

如:浮点数 -12345678.6 转byte

-12345678.6 转int向0取整-12345678,补码:

1111 1111 0100 0011 1001 1110 1011 0010

收缩转byte,截断低8位:

1011 0010

表示十进制78

收缩转char或short,截断低16位:

1001 1110 1011 0010

char是无符号的,十进制表示40626

short是有符号的,十进制表示-24910

 

### 话题7 水落石出——浮点结构的最终解密31

(1)存储格式

类型    符号位      指数域      有效位数域 
float  1位(第31位)  8位(第23~30位)  23位(第0~22位) 
double 1位(第63位) 11位(第52~62位)    52位(第0~51位) 

 

符号位:0为正,1为负

指数域:偏移量方式存储,2^x-1(X为指数位数)

 

(2)根据指数位和有效位不同,分三类

a.正规化浮点数 
当指数域不全为0并且不全为1,该浮点数就是正规化浮点数。

正规化浮点数的有效位数(小数部分)会在实际存储小数值的结果上加1。例如:float类型值99.5f的32位存储结构如下: 
0 10000101 10001110000000000000000 
二进制的有效位数为0.1000111,加1的二进制结果为1.1000111。而指数部分(133)减去偏移量(2^8-1=127)后的值为6,因此根据浮点值可以表示为v=s*m*2^e,99.5f就可以写成: 
99.5f=1*1.1000111*2^6

 

b.非正规化浮点数 
当指数域全为0并且有效位数域不全为0时,该浮点数就是非正规化浮点数。

需要注意的是,非正规化浮点数的指数值为1-偏移量。

例如,float类型值5.877472E-39f的32位存储结构如下: 
0 00000000 10000000000000000000000 
二进制的有效位数为0.1,实际上也就是这个值(不再加1),指数为1-偏移量,float类型的偏移量为127,即-126,因此该浮点数可以写成: 
5.877472E-39f=1*0.1*2^(-126)

 

c.特殊浮点数 

浮点数  符号位  指数域  有效位数域 
0     0    全为0   全为0 
-0     1    全为0   全为0 
正无穷大   0   全为1   全为0 
负无穷大   1   全为1   全为0 
NaN    任意   全为1  不全为0

 

(3)近似存储

十进制小数部分转换二进制采用的是乘2取整。

浮点数精度问题的原因:

例如:0.3小数位乘积永远取不到1,就算double类型有52位有效位也不能准确存储。

(4)打印浮点数的二进制形式

int value = Float.floatToIntBits(f);

String s = Integer.toBinaryString(value);

 

(5)浮点数之间的间隙

浮点数间隙随着浮点值的绝对值增大而增大

```java

// ulp 返回下一个float(double)类型浮点值x与参数的间隙

System.out.println(Math.ulp(0.3f));

 

float f = 88.88f;

// 下面的用法等价

//nextUp 返回正无穷方向的下一个数值

System.out.println(Math.nextUp(f));

//nextAfter 可以指定方向

System.out.println(Math.nextAfter(f,Float.POSITIVE_INFINITY));//POSITIVE_INFINITY 正无穷

```

(5)浮点精度丢失问题

float值1.6777216E7

十六精致表示:

0x1.0p24

二进制表示:

1 0000 0000 0000 0000 0000 0000

加1:

1 0000 0000 0000 0000 0000 0001

float有效位数只有23位,所以第24位丢失

 

(6)最近舍入

 

### 话题8 龙虎争霸——基本for 循环与加强型for 循环的对比45

增强型for循环局限:

在访问集合类元素的时候很方便,不用迭代器iterator

右边变量必须是数组或Iterator类型

底层实现也是基本的for循环

目录 目 录 第1章 基本概念 1 话题1 开门见山——测试你的Java水平 1 话题2 世外隐者——隐居深山的“关键字” 2 话题3 疑团满腹——标识符更深层的思考 6 话题4 鞭长莫及——我的特殊字符,你不能用! 10 话题5 移星换斗——从byte b = 1谈类型转换的神秘 16 话题6 扑朔迷离——浮点类型的种种悬疑 22 话题7 水落石出——浮点结构的最终解密 31 话题8 龙虎争霸——基本for循环与加强型for 循环的对比 45 第2章 运算符与表达式 52 话题9 莫衷一是——i+++j该如何计算? 52 话题10 千差万别——++i与i++仅是“先加”与“后加”的差别吗? 56 话题11 强大相径庭——相除与求余在Java中的具体表现 61 话题12 移形换位——移位运算的真实剖析 75 话题13 鞭辟近里——条件运算符(?:)的类型深入 81 话题14 井然有序——运算顺序的详细挖掘 86 话题15 异曲同工——交换变量的3种方式 90 话题16 择木而栖——开关选择表达式switch的类型内幕 95 第3章 String类 103 话题17 来龙去脉——“+”是怎样连接字符串的? 103 话题18 一成不变——不可修改的String对象 107 话题19 钩深索隐——String字符最大长度的探索 111 话题20 追本溯源——追寻String字面常量的“极限” 116 话题21 旧调重弹——再论equals方法与“==”的 区别 122 话题22 顺藤摸瓜——从字面常量到String常量池 136 第4章 方法、构造器与变量 143 话题23 相差无几——main方法很“特殊”吗? 143 话题24 一词多义——方法重载的详细说明 150 话题25 踵事增华——方法重写的真正条件 166 话题26 一叶障目——方法与成员变量的隐藏 177 话题27 发轫之始——执行初始化的构造器 182 话题28 殊途同归——成员变量不同的初始化方式 193 话题29 按部就班——初始化顺序与向前引用 206 第5章 类与接口 220 话题30 相辅相成——基本数据类型与包装类 220 话题31 分门别类——数组的阐述 232 话题32 规矩方圆——定义规范的接口类型 242 话题33 彻里至外——嵌套类型 248 话题34 不胜枚举——枚举的神秘 258 话题35 按部就班——加载、链接与初始化 265 话题36 择优录取——类型及其成员的选择 283 内容简介 本书分为5章,分别为“基本概念”,“运算符与表达式”,“String类”,“方法,构造器与变量”,“类与接口”。 通过以上方面介绍那些常见、常用却少为人知的Java知识。虽然内容相对基本,但都不是容易解答的。目前更多的开发人员(不乏多年开发经验者),也仅仅停留在Java表面的层次,而本书,将更深入一层地去讨论Java话题,令读者耳目一新,知其然,更知其所以然。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁星点点-

请我喝杯咖啡呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值