Skip to content

Commit b14da66

Browse files
committed
更新字面值常量
1 parent c1e0f83 commit b14da66

File tree

2 files changed

+171
-4
lines changed

2 files changed

+171
-4
lines changed

SUMMARY.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@
6060
* [优先级](book/04-Operators.md#优先级)
6161
* [赋值](book/04-Operators.md#赋值)
6262
* [算术运算符](book/04-Operators.md#算术运算符)
63-
* [自动递增和递减](book/04-Operators.md#自动递增和递减)
63+
* [递增和递减](book/04-Operators.md#递增和递减)
6464
* [关系运算符](book/04-Operators.md#关系运算符)
6565
* [逻辑运算符](book/04-Operators.md#逻辑运算符)
66-
* [字面值](book/04-Operators.md#字面值)
66+
* [字面值常量](book/04-Operators.md#字面值常量)
6767
* [按位运算符](book/04-Operators.md#按位运算符)
6868
* [移位运算符](book/04-Operators.md#移位运算符)
6969
* [三元运算符](book/04-Operators.md#三元运算符)

book/04-Operators.md

+169-2
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ x = a * (-b);
258258

259259

260260
<!-- Auto-Increment-and-Decrement -->
261-
## 自动递增和递减
261+
## 递增和递减
262262

263263

264264
和 C 语言类似,Java 提供了许多快捷运算方式。快捷运算可使代码可读性,可写性都更强。其中包括递增 `++` 和递减 `--`,意为“增加或减少一个单位”。举个例子来说,假设 a 是一个 **int** 类型的值,则表达式 `++a` 就等价于 `a = a + 1`。 递增和递减运算符不仅可以修改变量,还可以生成变量的值。
@@ -471,7 +471,174 @@ test1(0)&& test2(2)&& test3(2)
471471

472472

473473
<!-- Literals -->
474-
## 字面值
474+
## 字面值常量
475+
476+
477+
通常,当我们向程序中插入一个字面值常量(**Literal**)时,编译器会确切地识别它的类型。当类型不明确时,必须辅以字面值常量关联来帮助编译器识别。代码示例:
478+
479+
```JAVA
480+
// operators/Literals.java
481+
public class Literals {
482+
public static void main(String[] args) {
483+
int i1 = 0x2f; // 16进制 (小写)
484+
System.out.println(
485+
"i1: " + Integer.toBinaryString(i1));
486+
int i2 = 0X2F; // 16进制 (大写)
487+
System.out.println(
488+
"i2: " + Integer.toBinaryString(i2));
489+
int i3 = 0177; // 8进制 (前导0)
490+
System.out.println(
491+
"i3: " + Integer.toBinaryString(i3));
492+
char c = 0xffff; // 最大 char 型16进制值
493+
System.out.println(
494+
"c: " + Integer.toBinaryString(c));
495+
byte b = 0x7f; // 最大 byte 型16进制值 10101111;
496+
System.out.println(
497+
"b: " + Integer.toBinaryString(b));
498+
short s = 0x7fff; // 最大 short 型16进制值
499+
System.out.println(
500+
"s: " + Integer.toBinaryString(s));
501+
long n1 = 200L; // long 型后缀
502+
long n2 = 200l; // long 型后缀 (容易与数值1混淆)
503+
long n3 = 200;
504+
505+
// Java 7 二进制字面值常量:
506+
byte blb = (byte)0b00110101;
507+
System.out.println(
508+
"blb: " + Integer.toBinaryString(blb));
509+
short bls = (short)0B0010111110101111;
510+
System.out.println(
511+
"bls: " + Integer.toBinaryString(bls));
512+
int bli = 0b00101111101011111010111110101111;
513+
System.out.println(
514+
"bli: " + Integer.toBinaryString(bli));
515+
long bll = 0b00101111101011111010111110101111;
516+
System.out.println(
517+
"bll: " + Long.toBinaryString(bll));
518+
float f1 = 1;
519+
float f2 = 1F; // float 型后缀
520+
float f3 = 1f; // float 型后缀
521+
double d1 = 1d; // double 型后缀
522+
double d2 = 1D; // double 型后缀
523+
// (long 型的字面值同样适用于十六进制和8进制 )
524+
}
525+
}
526+
```
527+
528+
输出结果:
529+
530+
```
531+
i1: 101111
532+
i2: 101111
533+
i3: 1111111
534+
c: 1111111111111111
535+
b: 1111111
536+
s: 111111111111111
537+
blb: 110101
538+
bls: 10111110101111
539+
bli: 101111101011111010111110101111
540+
bll: 101111101011111010111110101111
541+
```
542+
543+
在文本值的后面添加字面值常量可以让编译器识别该文本值的类型。对于 **Long** 型数值,结尾使用大写 `L` 或小写 `l` 皆可(不推荐使用 `l`,因为容易与阿拉伯数值 1 混淆)。大写 `F` 或小写 `f` 表示 **float** 浮点数。大写 `D` 或小写 `d` 表示 **double** 双精度。
544+
545+
546+
十六进制(以 16 为基数),适用于所有整型数据类型,由前导 `0x``0x` 表示,后跟 0-9 或 a-f (大写或小写)。如果我们在初始化某个类型的数值时,赋值超出其范围,那么编译器会报错(不管值的数字形式如何)。在上例的代码中,**char****byte****short** 的值已经是最大了。如果超过这些值,编译器将自动转型为 **int**,并且我们需要声明强制转换(强制转换将在本章后面定义)。这告诉我们已越过该类型的范围界限。
547+
548+
八进制(以 8 为基数)由 0~7 之间的数字和前导零 `0` 表示。
549+
550+
Java 7 引入了二进制的字面值常量,由前导 `0B``0B` 表示,它可以初始化所有的整数类型。
551+
552+
使用整型数值类型时,显示其二进制形式会很有用。在 Long 型和 Integer 型中这很容易实现,调用其静态的 **toBinaryString()** 方法即可。 但是请注意,若将较小的类型传递给 **Integer.tobinarystring()** 时,类型将自动转换为 **int**
553+
554+
<!-- Underscores in Literals -->
555+
### 下划线
556+
557+
558+
Java 7 中有一个深思熟虑的补充:我们可以在数字文字中包含下划线 `_`,以使结果更清晰。这对于大数值的分组数字特别有用。代码示例:
559+
560+
561+
```JAVA
562+
// operators/Underscores.java
563+
public class Underscores {
564+
public static void main(String[] args) {
565+
double d = 341_435_936.445_667;
566+
System.out.println(d);
567+
int bin = 0b0010_1111_1010_1111_1010_1111_1010_1111;
568+
System.out.println(Integer.toBinaryString(bin));
569+
System.out.printf("%x%n", bin); // [1]
570+
long hex = 0x7f_e9_b7_aa;
571+
System.out.printf("%x%n", hex);
572+
}
573+
}
574+
```
575+
576+
输出结果:
577+
578+
```
579+
3.41435936445667E8
580+
101111101011111010111110101111
581+
2fafafaf
582+
7fe9b7aa
583+
```
584+
585+
586+
下面是合理使用的规则:
587+
588+
1. 仅限单 `_`,不能多条相连。
589+
2. 数值开头和结尾不允许出现 `_`
590+
3. `F``D``L`的前后禁止出现 `_`
591+
4. 二进制前导 `b` 和 十六进制 `x` 前后禁止出现 `_`
592+
593+
594+
[1] 注意 `%n`的使用。熟悉 C 风格的程序员可能习惯于看到 `\n` 来表示换行符。问题在于它给你的是一个“Unix风格”的换行符。此外,如果我们使用的是 Windows,则必须指定 `\r\n`。这种差异的包袱应该由编程语言来解决。这就是Java用 `%n` 实现的,忽略平台间差异生成适当的换行符。但当你使用 `System.out.printf()``System.out.format()` 时。对于 `System.out.println()`,我们仍然必须使用 `\n`;如果你使用 `%n``println()` 只会输出 `%n` 而不是换行符。
595+
596+
597+
<!-- Exponential Notation -->
598+
### 指数计数法
599+
600+
指数总是采用一种我认为很不直观的记号方法:
601+
602+
```JAVA
603+
// operators/Exponents.java
604+
// "e" 表示 10 的几次幂
605+
public class Exponents {
606+
public static void main(String[] args) {
607+
// 大写 E 和小写 e 的效果相同:
608+
float expFloat = 1.39e-43f;
609+
expFloat = 1.39E-43f;
610+
System.out.println(expFloat);
611+
double expDouble = 47e47d; // 'd' 是可选的
612+
double expDouble2 = 47e47; // 自动转换为 double
613+
System.out.println(expDouble);
614+
}
615+
}
616+
```
617+
618+
输出结果:
619+
620+
```
621+
1.39E-43
622+
4.7E48
623+
```
624+
625+
在科学与工程学领域,“e”代表自然对数的基数,约等于 2.718 (Java 一种更精确的 **double** 值采用 **Math.E** 的形式)。它在类似 “1.39×e 的 -47 次方”这样的指数表达式中使用,意味着“1.39×2.718 的-47次方”。然而,自 FORTRAN 语言发明后,人们自然而然地觉得e 代表 “10几次幂”。这种做法显得颇为古怪,因为 FORTRAN 最初面向的是科学与工程设计领域。
626+
627+
理所当然,它的设计者应对这样的混淆概念持谨慎态度 [^2]。但不管怎样,这种特别的表达方法在 C,C++ 以及现在的 Java 中顽固地保留下来了。所以倘若习惯 e 作为自然对数的基数使用,那么在 Java 中看到类似“1.39e-47f”这样的表达式时,请转换你的思维,从程序设计的角度思考它;它真正的含义是“1.39×10 的-47次方”。
628+
629+
注意如果编译器能够正确地识别类型,就不必使用尾随字面值常量。对于下述语句:
630+
631+
```JAVA
632+
long n3 = 200;
633+
```
634+
635+
它并不存在含糊不清的地方,所以 200 后面的 L 大可省去。然而,对于下述语句:
636+
637+
```
638+
float f4 = 1e-47f; //10 的幂数
639+
```
640+
641+
编译器通常会将指数作为 **double** 类型来处理,所以假若没有这个尾随的 `f`,编辑器就会报错,提示我们应该将 **double** 型转换成 **float**型。
475642

476643

477644
<!-- Bitwise-Operators -->

0 commit comments

Comments
 (0)