文章目录
基本数据类型
- 整数类型:byte、short、int、long (1,2,4,8)
- 浮点数类型:float、double (4,8)
- 字符类型:char (2)
- 布尔类型:boolean (1/8,1bit)
整型
- byte:-128 ~ 127
- short: -32768 ~ 32767
- int: -2147483648 ~ 2147483647
- long: -9223372036854775808 ~ 9223372036854775807
存储原理
计算机中整数一律采用补码的形式存储,读取时需要将补码转换为原码。
- 原码:一个数的二进制形式。
- 反码:正负数区别对待,正数的反码就是原码,负数的反码就是将原码中除符号位以外的所有位(数值位)取反。
- 补码:正负数区别对待,正数的补码也是原码,负数的补码时其反码加1。
整数运算
- 溢出:超出范围就会产生溢出,溢出不会报错。
- 移位运算:<<1 等价于 x2,>>1 等价于 ÷2 。
- 位运算:与&、或|、非~、异或^。
- 类型自动提示与强制转型
注意:
- long类型需要在数的后面加“L”。
- 位数过大的数可用下划线“_”进行分隔,1_000_000_000。
- 表示不同进制的整数:0x前缀表示十六进制,0前缀表示八进制,0b前缀表示二进制。
浮点型
float
的范围为-2^128 ~ +2^127,也即-3.40E+38 ~ +3.40E+38;double
的范围为-2^1024 ~ +2^1023,也即-1.79E+308 ~ +1.79E+308。
浮点数的存储原理
s表示符号位,M表示尾数,E表示阶码。
V
=
(
−
1
)
S
✖
1.
M
✖
2
E
−
127
V = (-1)^S ✖ 1.M ✖ 2^{E-127}
V=(−1)S✖1.M✖2E−127
-
单精度浮点数:32位,最高位保存s,中间8位保存E,最后23位保存M。
-
双精度浮点数:64位,最高位保存s,中间11位保存E,最后52位保存M。
浮点数运算
- 溢出:整数运算在除数为
0
时会报错,而浮点数运算在除数为0
时,不会报错,但会返回几个特殊值:NaN
表示Not a Number(0.0/0)Infinity
表示无穷大-Infinity
表示负无穷大
注意:
float
类型需要在后面加上“f”后缀。- 在一个复杂的四则运算中,两个整数的运算不会出现自动提升的情况。
- 强制转型为整数时会截断小数部分。(如果想四舍五入的话可以加上0.5再强制转型)
布尔类型
- true
- false
理论上存储布尔类型只需要1bit,但是通常JVM内部会把
boolean
表示为4字节整数。
布尔运算
关系运算符的优先级从高到低依次是:
!
>
,>=
,<
,<=
==
,!=
&&
||
短路运算
&& 和 || 在计算第一个表达式时如果没有满足条件就会放弃执行第二个表达式。
字符类型
Java的char
类型除了可表示标准的ASCII外,还可以表示Unicode字符。
还可以直接用转义字符\u
+Unicode编码来表示一个字符。
**Unicode字符集:**Unicode(又称统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
utf-8编码规则:UTF-8 就是使用变长字节表示,字节数可变,这个变化与Unicode 编号的大小有关,编号小的使用的字节就少,编号大的使用的字节就多。使用的字节个数从 1 到 4 个不等。
字符串类型
字符串类型是引用类型。一个字符串可以存储0个到任意个字符。
字符串连接:"+"。
多行字符串:Java13开始,可以使用"""……"""
表示多行字符串,每行前面共同的空格会被去掉。
不可变特性
字符串的内容不可变,当再次赋值时,字符串变量只是更换一个指向,原来指向的字符串并没有消失。
常见的转义字符包括:
\"
表示字符"
\'
表示字符'
\\
表示字符\
\n
表示换行符\r
表示回车符\t
表示Tab\u####
表示一个Unicode编码的字符
引用类型
类似C语言的指针,内部存储一个“地址“,指向某个对象在内存的位置。
空值null
引用类型的变量可以指向一个空值null
,它表示不存在,即该变量不指向任何对象,空值不是""。
常量
定义变量时,加上final
修饰符,该变量就变成了常量,初始化后不能再赋值。
根据习惯,常量名通常全部大写。
var关键字
java10新特性,可以省略变量类型。
不过有三点要求:
- 只能用于局部变量上;
- 声明时必须初始化;
- 不能用作方法参数。
变量的作用域
定义变量时,要遵循作用域最小化原则,尽量将变量定义在尽可能小的作用域,并且,不要重复使用变量名。
数组类型
-
数组也是引用类型,再次赋值情况与字符串相同。
-
数组所有元素初始化为默认值,整型都是
0
,浮点型是0.0
,布尔型是false
; -
数组一旦创建后,大小就不可改变。
输入和输出
格式化输出
通过使用占位符%?
,printf()
可以把后面的参数格式化成指定格式。
System.out.printf("%.2f\n", d); // 显示两位小数3.14
占位符 | 说明 |
---|---|
%d | 格式化输出整数 |
%x | 格式化输出十六进制整数 |
%f | 格式化输出浮点数 |
%e | 格式化输出科学计数法表示的浮点数 |
%s | 格式化字符串 |
连续两个%%表示一个%字符本身。
输入
Java提供Scanner对象来方便输入,读取对应的类型可以使用:scanner.nextLine()
/ nextInt()
/ nextDouble()
。
switch
从Java 12开始,switch
语句升级为更简洁的表达式语法,使用类似模式匹配(Pattern Matching)的方法,保证只有一种路径会被执行,并且不需要break
语句。
switch (fruit) {
case "apple" -> System.out.println("Selected apple");
case "pear" -> System.out.println("Selected pear");
case "mango" -> {
System.out.println("Selected mango");
System.out.println("Good choice!");
}
default -> System.out.println("No fruit selected");
}
还可以作为表达式直接返回值:
int opt = switch (fruit) {
case "apple" -> 1;
case "pear", "mango" -> 2;
default -> 0;
}; // 注意赋值语句要以;结束
yield
如果需要复杂的语句,可以写很多语句,放到{...}
里,然后,用yield
返回一个值作为switch
语句的返回值。(Java14)
default -> {
int code = fruit.hashCode();
yield code; // switch语句返回值
}
for each 循环
访问数组每个元素的值。
int[] ns = { 1, 4, 9, 16, 25 };
for (int n : ns) {
System.out.println(n);
}
命令行参数
Java程序的入口是main
方法,而main
方法可以接受一个命令行参数,它是一个String[]
数组。
这个命令行参数由JVM接收用户输入并传给main
方法:
比如:
public class Main {
public static void main(String[] args) {
for (String arg : args) {
if ("-version".equals(arg)) {
System.out.println("v 1.0");
break;
}
}
}
}
$ javac Main.java
$ java Main -version
v 1.0