[toc]
3.3 数据类型
p31:
java
没有无符号unsigned
类型,但是可以把有符号整数值当成无符号计算。只要不溢出,加、减、乘都能正常计算。对于其他运算,需要调用Byte.toUnsignedInt()
方法来得到一个0~255
的int
值。P31:可以使用16进制表示浮点数,如:
0.125 = 0x1.0p-3
。p表示指数,基数是2,尾数采用16进制,指数采用十进制。p32:
char
类型的值可以表示为十六进制,范围\u0000 - \uFFFF
。Unicode
转义序列会在解析代码之前被处理。
"\u0022+\u0022"
会变成""+""
。
// \u000A is a newline
会报错,因为\u000A
是换行符。
// look inside c:\users
也会报错,因为\u
后面没有跟着4个16进制数。
3.4 变量与常量
-
p34:变量名以字母开头,由字母和数字组成。“字母”可以是
Unicode
中任何外语“字母”;“数字”可以是Unicode
中任何外语“数字”。判断一个Unicode
字符是不是字母,可以用Character.isJavaIdentifierStart()
和Character
isJavaIdentifierPart()
方法来检查。
3.5 运算符
p38:类方法
Math.floorMod(int a, int b)
进行求模运算,当被除数a
是负数时,余数总为非负数。当除数b
为负数,返回值为负。p39:
StrictMath
类实现了“可自由分发的数学库”的算法,确保在所有平台上得到相同的结果(有些处理器支持扩展的精度,普通的算术运算符,在不同机器上的运算结果精度不同)。p40:
Math
类有一些方法,使整数运算更安全。Math.multiplyExact()
addExact
subtractExact
incrementExact
decrementExact
negateExact
都能正确处理int
和long
参数。当运算溢出或参数不对时会抛异常。可以捕获这个异常,而不是允许它给出一个错误的结果,然后继续运行。-
p41:强制类型转换会把数截断,例如:
double x = 9.997; int nx = (int) x; //nx的值为9 nx= (int) Math.round(x); //nx为10,round方法返回long byte b = (byte) 300; //b的值为44
p43:移位运算符的右操作数会进行取模,左操作数是
int
就模32
,左操作数是long
就模64
。例如1<<35
等于1<<3
。p43:位运算符
>>>
会用0
填充高位,而>>
用符号位
填充高位。
3.6 字符串
p49:
boolean Character.isSurrogate(char)
检测一个char
值(代码单元
)是否在代理区(surrogate
)。
boolean Character.isSupplementaryCodePoint(int)
检测一个int
值是否辅助字符码点。-
p54:构建字符串。
StringBuilder builder = new StringBuilder();
StringBuilder API
3.7 输入与输出
-
p55:通过控制台输入,首先要构造一个与"标准输入流"
System.in
关联的Scanner
对象。Scanner
在java.util
包中。Scanner in = new Scanner(System.in);
因为输入是可见的,所以
Scanner
类不适用于从控制台读取密码。Java 6
特别引入了Console
类来实现这个目的。为安全起见,返回的密码放在char
数组中,而不是字符串中。处理完密码后,应该马上修改数组元素的值。
java Console con = System.console(); String name = cons.readLine("User name:"); char[] passwd = cons.readPassword("Password:");
Scanner & Console API
-
p58:格式化输出
System.out.printf
。
格式转换符 Conversions for printf
标志 flags for printf
-
p59:也可以用类方法
String.format
创建一个格式化字符串,而不打印输出。String str = String.format("Hello, %s. Next year, you'll be %d", name, age);
-
p59:用
printf
方法输出格式化的日期与时间。这个转换符包括两个字母,以t
开始,以下表中的任意字母结束。例如:System.out.printf("%tc", new Date()); //将输出以下字符 Mon Feb 09 18:05:19 PST 2015
日期和时间的转换符
-
p60:可以按参数索引来格式化,索引必须紧跟在
%
后面,并以$
终止。或选用<
标志,它指示前面格式说明符中的参数将被再次使用。System.out.printf("%1$s %2$tB %2$te, %2$tY", "Due date:", new Date()); System.out.printf("%s %tb %<te, %<tY", "Due date:", new Date()); //两种方法都会输出下面的字符 Due date: Febrary 9, 2015
-
p60:printf 格式说明符的语法图
-
p61:
读取
一个文件,需要构造Scanner
对象,例如:Scanner in = new Scanner(Path.of("myfile.txt"), StandardCharsets.UTF_8); //文件名中的反斜杠前面,必须再加一个反斜杠,例如:"C:\\users\\myfile.txt"。
写入
一个文件,需要构造PrintWriter
对象,例如:PrintWriter out = new PrintWriter("myfile.txt", StandardCharsets.UTF_8); //如果文件不存在,将创建该文件
当使用一个
相对文件名
时,文件位于相对于Java
虚拟机启动目录
的位置。如果使用IDE
,可以使用下面的方法找到当前目录的位置:String dir = System.getProperty("user.dir");
如果构造
Scanner
对象时,文件不存在,或者构造PrintWriter
对象时,文件名无法创建,都会产生IOException
异常。
3.8 控制流程
-
p72:针对
switch
语句,如果在case
分支的末尾没有break
,这种情况相当危险。可以在编译时加上编译选项,让编译器检查这种错误:javac -Xlint:fallthrough Test.java
如果确实想用这种行为,可以为其外围方法加一个注解:
@SuppressWarnings("fallthrough")
这样就不会生成警告。
p73:
switch
可以处理char
byte
short
int
常量表达式
枚举常量
字符串字面量(从Java7开始)
。p75:
break
语句可以带标签
,可以将标签
应用到任何语句(包括语句块)。
break label;
语句将会跳转到带标签的语句块的末尾。p76:在
for
循环中,continue
语句会跳转到for
循环的变量“更新”部分。continue
语句也可以带标签。
3.9 大数
-
p76:
java.math
包中有两个很有用的类BigInteger
和BigDecimal
。可以处理任意长度的数字,进行任意精度的整数或浮点数运算。Big number API//可以用构造函数,把一个字符串转换为大数 BigInteger reallyBig = new BigInteger("22223224478962942044557979"); //把下面这条语句改写为使用大数 m = m * (n - k) / i; //变为 m = m.multiply(BigInteger.valueOf(n - k)).divide(BigInteger.valueOf(i));
3.10 数组
-
p79:数组的长度可以为0。
int[] a= new int[n]; //声明一个数组 int[] prime={2,3,5,}; //声明并初始化。最后一个值后面允许有逗号。 //可以声明匿名数组,用来给另一个数组赋值 prime = new int[] {17, 19, 23};
-
p81:
for each
可以依次处理数组中每个元素:for(var : collection) statements
其中 var 是一个临时变量,collection 这一表达式可以是任何实现了 Iterable 接口的类对象。
for(int element : a) System<