本文对《Java核心技术 I》中开发者容易忽视和重要的知识点进行总结,不包含一般开发者都知道内容。大标题后括号的数字代表书中对应的章节。
一、Java的基本程序设计结构(3)
1. 整数表示
可以为数字字面量加上下划线,这些下划线只是为了让人更易读。Java编译器会去除这些下划线。
int n = 1_000_000_000;
System.out.println(n);
// 输出
1000000000
2. 无符号类型
Java 中没有原生的无符号整数类型。所有的整数类型(byte
、short
、int
、long
)都是带符号的。不过,Java 提供了某些方法来模拟无符号行为,特别是对于 int
和 long
类型。
Java 8 引入的 Integer
类中的 toUnsignedLong(int x)
和 divideUnsigned(int x, int y)
方法主要用于支持无符号整数的操作,尽管 int
类型本身是带符号的。
2.1 toUnsignedLong(int x)
该方法将一个带符号的 int
转换为无符号的 long
类型。由于 int
类型是 32 位,且在 Java 中是有符号的,它的范围是 -2^31
到 2^31-1
,而无符号 int
的范围是 0
到 2^32-1
。通过该方法,可以将带符号的 int
值转换为无符号的 long
值来处理。
int signedInt = -1; // 带符号的 int 值
long unsignedLong = Integer.toUnsignedLong(signedInt); // 转换为无符号 long
System.out.println(unsignedLong); // 输出:4294967295
// -1 二进制是 11111111 11111111 11111111 11111111,转成无符号就是把前面二进制直接当成原码,求值为2^32-1即4294967295
// 正常负数的值应该是 上面二进制的各个位取反最后+1
2.2 divideUnsigned(int x, int y)
该方法执行两个无符号 int
值的除法操作,并返回无符号的结果。它的作用类似于普通的 x / y
,但是它是以无符号的方式来处理运算,即忽略符号位。
int x = 10;
int y = 3;
int result = Integer.divideUnsigned(x, y); // 无符号除法
System.out.println(result); // 输出:3
2.3 remainderUnsigned(int x, int y)
这个方法与 divideUnsigned
类似,但是它返回的是无符号的余数。
int x = 10;
int y = 3;
int remainder = Integer.remainderUnsigned(x, y); // 无符号余数
System.out.println(remainder); // 输出:1
无符号数的加减乘法在二进制层面与有符号数一致,因为它们使用相同的二进制表示,只是解释方式不同。所以加减乘法可以直接使用。
3. double 类型
float 类型的数值有一个后缀 F 或 f(例如,3.14F)。没有后缀 F 的浮点数值(如3.14)总是默认为 double 类型。可选地,也可以在double数值后面添加后缀 D 或 d。
所有浮点数计算都遵循 IEEE 754 规范,具体来说,有3个特殊的浮点数值表示溢出和出错的情况。
- 正无穷大(POSITIVE_INFINITY)
- 负无穷(NEGATIVE_INFINITY)
- NaN(不是一个数)
例如,一个正整数除以0的结果为正无穷大,计算0/0或负数的平方根结果为NaN。
Double x = 1.0;
if (x != Double.POSITIVE_INFINITY) {
System.out.println("x is not POSITIVE_INFINITY");
}
4. 右移操作
>>
和 >>>
都是按照位模式右移的运算符,但有略微区别。
-
>>
是带符号的右移操作符,叫做 算数右移。会保持符号位不变。 -
>>>
是无符号右移操作符,叫做 逻辑右移。不管正负数,都用 0 填充最高位。
int a = -8; // 二进制:11111111 11111111 11111111 11111000 (补码形式)
int b = a >> 2; // 右移 2 位
System.out.println(b); // 输出:-2
-8
右移两位后是 11111111 11111111 11111111 11111110
,负数在计算机中是以补码的形式存储,其原码是各个位取反,再+1。00000000 00000000 00000000 00000001
+ 1 = 00000000 00000000 00000000 00000010
(原码是2)
int a = -8; // 二进制:11111111 11111111 11111111 11111000 (补码形式)
int b = a >>> 2; // 右移 2 位,高位补 0
System.out.println(b); // 输出:1073741822
-8
右移两位后是 00111111 11111111 11111111 11111110
,(1073741822)
5. char类型
UTF-8 和 UTF-16 是两种常用的字符编码方式。
-
UTF-8是一种可变长度的字符编码,它将 Unicode 字符集中的字符编码成 1 到 4 个字节(8 位),使用 1 个字节到 4 个字节表示一个字符。其中前128个字符(ASCII)采用1字节
-
UTF-16也是一种可变长度的字符编码方式,但它将 Unicode 字符集中的字符编码成 2 个字节或 4 个字节,并且对于大多数常用字符(前128个字节),使用 2 个字节来表示。
Java中的 char类型 使用的就是 UTF-16,其中 UTF-16 有一个代码单元的概念,即表示一个字符的最小存储单位,UTF-16的代码单元是2字节。
观察下面代码可以发现,charAt
返回的是一个代码单元,那么对于占用两个代码单元的字符串就会出现奇怪的问题。所以尽量避免使用 Char 类型。
String s = "\uD83D\uDE00hello"; // 这个字符串实际是
标签:知识点,Java,String,汇总,System,Person,println,public,out
From: https://blog.csdn.net/m0_74065705/article/details/144676465