1.数据类型
1.1、八种基本数据类型
最大值 | 最小值 | 默认值 | 占用字节 | 包装类 | 数据类型 | |
---|---|---|---|---|---|---|
byte | 2^7-1 | -2^7 | 0 | 1 | Byte | 字节型 |
short | 2^15-1 | -2^15 | 0 | 2 | Short | 短整型 |
int | 2^31-1 | -2^31 | 0 | 4 | Intrger | 整型 |
long | 2^63-1 | -2^63 | 0L | 8 | Long | 长整型 |
float | 3.4028235E38 | 1.4E - 45 | 0.0f | 4 | Float | 单精度浮点型 |
double | 1.7976931348623157E308 | 4.9E-324 | 0.0d | 8 | Double | 双精度浮点型 |
char | \uffff | \u0000 | \u0000 | 2 | Character | 字符型 |
boolean | 只有两种取值true和false | false | 未明确规定 | Boolean | 布尔型 |
示例代码如下:
int num = 10;
long a = 12L;
float f = 11.0f;
char ch = 'a';
boolean b = true;
注:
①java中默认整型字面值为int类型,默认浮点型字面值为double类型
②给long类型的变量赋值时要在值后加L;给float类型的变量赋值时要在值后加f
③float和double不能用来表示精确的值
1.2、引用数据类型
String、类、数组、接口、抽象类、枚举(这里只简单了解String,其他后续逐步了解)
String为字符串类型,示例代码如下:
String name = "zhangsan";
字符串的“+”操作,表示字符串的拼接:
String a = "hello";
String b = "world";
String str = a + b;
System.out.println(str);//helloworld
字符串还可以和整数进行拼接:
String str = "result = ";
int a = 10;
int b = 20;
String result = str + a + b;
System.out.println(result);//result = 1020
以上代码说明了当一个“+”表达式存在字符串的时候,都是执行字符串拼接行为。因此我们可以使用System.out.println();很方便的同时打印多个字符串或数字:
int a = 10;
int b = 20;
System.out.println("a = " + a + ",b = " + b);//a = 10,b = 20
字符串中一些特定的不太方便直接表示的字符需要进行转义
转义字符 | 作用 |
---|---|
\n | 换行(回车) |
\t | 水平制表符(tab) |
\’ | 单引号 |
\" | 双引号 |
\\ | 反斜杠 |
示例代码如下:
System.out.println("\"Hello World\"");//"Hello World"
1.3、变量
变量的命名规则:
①一个变量名只能包含数字, 字母, 下划线
②数字不能开头.
③变量名是大小写敏感的. 即 num 和 Num 是两个不同的变量.
④变量命名要具有描述性, 见名知意.
⑤变量名不宜使用拼音(但是不绝对).
⑥变量名的词性推荐使用名词.
⑦变量命名推荐 小驼峰命名法, 当一个变量名由多个单词构成的时候, 除了第一个单词之外, 其他单词首字母都大写
示例代码如下:
int studentScore = 98;
String studentName = "zhangsan";
注: 虽然语法上也允许使用中文/美元符($)命名变量,但是强烈不建议这么做
变量的作用域:
变量生效的范围,一般时变量定义所在的代码块(大括号内),示例代码如下:
class Test01 {
public static void main(String[] args){
{
int a = 10;
System.out.println(a);//10
}
System.out.println(a);//编译报错,变量a的作用域是上面大括号
}
}
class Test02 {
public static void main(String[] args){
int a = 10;
{
int a = 20;//编译报错,已在main方法中定义了变量a
System.out.println(a);//10,变量a作用域为main方法
a = 20;//可以修改变量a的值
System.out.println(a);//20
}
System.out.println(a);//20,变量a的值已经变成20
}
}
1.4、常量
上面讨论的都是各种规则的变量, 每种类型的变量也对应着一种相同类型的常量.常量指的是运行时类型不能发生改变.常量主要有以下两种体现形式:
①字面值常量:
10 // int 字面值常量(十进制)
010 // int 字面值常量(八进制) 由数字 0 开头. 010 也就是十进制的 8
0x10 // int 字面值常量(十六进制) 由数字 0x 开头. 0x10 也就是十进制的 16
10L // long 字面值常量. 也可以写作 10l (小写的L)
1.0 // double 字面值常量. 也可以写作 1.0d 或者 1.0D
1.5e2 // double 字面值常量. 科学计数法表示. 相当于 1.5 * 10^2
1.0f // float 字面值常量, 也可以写作 1.0F
true // boolen 字面值常量, 同样的还有 false
‘a’ // char 字面值常量, 单引号中只能有一个字符
“abc” // String 字面值常量, 双引号中可以有多个字符
②final关键字修饰的常量:
final int num = 10;
num = 20;//编译报错,无法为最终变量num分配值
常量不能再程序运行过程中发生修改
1.5、类型转换
java作为一个强类型编程语言,当不同类型之间相互转换时,有严格的检验
示例代码如下:
int和long/double相互赋值
int a = 10;
long b = 20L;
a = b;//编译报错,提示可能损失精度
b = a;//编译通过
int a = 10;
double b = 20.0;
a = b;//编译报错,提示可能损失精度
b = a;//编译通过
long类型表示的范围比int大,可以将int类型的值赋给long,但是不能将long类型的值赋给int
double类型和int类型同理
结论: 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型, 反之则不行
int和boolean相互赋值
int a = 1;
boolean b = false;
b = a;//编译报错,提示不兼容类型
a = b;//编译报错,提示不兼容类型
结论: int和boolean是两种毫不相干的类型,不能相互赋值
int字面值常量给byte赋值
byte a = 125;//编译通过
byte b = 128;//编译报错,提示从int转到byte可能会有损失
结论: 使用字面值常量赋值的时候,java会自动进行一些检查,判定值是否合理
1.6、强制类型转换
int a;
double b = 10.5;
a = (int)b;//a=10
int a = 1;
boolean b = false;
b = (boolean)a;//编译报错,提示不兼容类型
结论:
①使用(类型)的方法double可以强制转换为int类型,但是可能损失精度,如10.5变成10
②强制类型转换不一定能成功,互不相干的类型之间无法强转
1.7数值提升
int和long混合运算
int a = 10;
long b = 20;
int c = a + b; // 编译报错, 提示将 long 转成 int 会丢失精度
long d = a + b; // 编译通过
结论: 当 int 和 long 混合运算的时候, int 会提升成 long, 得到的结果仍然是 long 类型, 需要使用 long 类型的变量来接收结果; 如果非要用 int 来接收结果, 就需要使用强制类型转换
byte和byte的运算
byte a = 10;
byte b = 20;
byte c = a + b;
System.out.println(c);
// 编译报错
Test.java:5: 错误: 不兼容的类型: 从int转换到byte可能会有损失
byte c = a + b;
^
结论:
①byte 和 byte 都是相同类型, 但是出现编译报错. 原因是, 虽然 a 和 b 都是 byte, 但是计算 a + b 会先将 a 和 b 都提升成 int, 再进行计算, 得到的结果也是 int, 这是赋给 c, 就会出现上述错误
②由于计算机的 CPU 通常是按照 4 个字节为单位从内存中读写数据. 为了硬件上实现方便, 诸如 byte 和 short 这种低于4 个字节的类型, 会先提升成 int, 再参与计算
上诉代码正确写法:
byte a = 10;
byte b = 20;
byte c = (byte)(a + b);
System.out.println(c);//30
1.8、int和String类型相互转换
int转换成String:
//方法1
int num = 10;
String str1 = num + "20";
//方法2
String str2 = String.valueOf(num);
String转换成int:
String str = "100";
int num = Integer.valueOf(str);
2.运算符
2.1、算术运算符
①基本四则运算符:+ - * / %
int/int的结果还是int,需要使用double来计算
int a = 5;
int b = 2;
System.out.println(a / b);//2
0不能做除数
int a = 1;
int b = 0;
System.out.println(a / b);//编译通过,运行报错,算数异常
//ArithmeticException
%表示取余数,不仅可以对int求模,也能对double求模
System.out.println(11.5 % 2.0);//1.5
②增量赋值运算符:+= -= *= /= %=
int a = 10;
a += 1;//a = a + 1
System.out.println(a);//11
③自增自减运算符:++ –
int a = 10;
a++;//这里的a++可以替换为++a,仅限于此
System.out.println(a);//11
int a = 10;
int b = a++;
System.out.println(b);//10
int c = ++a;
System.out,println(c);//11
结论:
①如果不取自增运算的表达式的返回值, 则前置自增和后置自增没有区别
②如果取表达式的返回值, 则前置自增的返回值是自增之后的值, 后置自增的返回值是自增之前的值
2.2、关系运算符
== != < > <= >=
int a = 1;
int b = 2;
System.out.println(a == b);//false
System.out.println(a != b);//true
System.out.println(a >= b);//false
System.out.println(a <= b);//true
System.out.println(!(a < b));//false
注: 关系运算符返回值都是boolean类型
2.3、逻辑运算符
&& || !
注: 逻辑运算符的操作数(操作数往往是关系运算符的结果)和返回值都是 boolean
①逻辑与 &&
两个操作数都为true时结果为true,否则为false
int a = 10;
int b = 20;
System.out.println(a < b && a != b);//true
②逻辑或 ||
两个操作数都为false时结果为false,否则为true
int a = 10;
int b = 20;
System.out.println(a > b || a = b);//false
③逻辑非 !
操作数为 true, 结果为 false; 操作数为 false, 结果为 true(这是个单目运算符, 只有一个操作数)
int a = 10;
int b = 20;
System.out.println(!(a > b));//true
④短路求值
&&和 || 遵守短路求值的规则
System.out.println(10 > 20 && 10 / 0 == 0);//flase
System.out.println(10 < 20 || 10 / 0 == 0);//true
结论:
①对于 && , 如果左侧表达式值为 false, 则表达式的整体的值一定是 false, 无需计算右侧表达式
②对于 ||, 如果左侧表达式值为 true, 则表达式的整体的值一定是 true, 无需计算右侧表达式
⑤&和 | (不推荐使用)
& 和 | 如果操作数为 boolean 的时候, 也表示逻辑运算. 但是和 && 以及 || 相比, 它们不支持短路求值
System.out.println(10 > 20 & 10 / 0 == 0); // 报错
System.out.println(10 < 20 | 10 / 0 == 0); // 报错
2.4、位运算符
& | ~ ^
java中对数据的操作的最小单位不是字节, 而是二进制位;
位操作表示 按二进制位运算. 计算机中都是使用二进制来表示数据的(01构成的序列), 按位运算就是在按照二进制位的每一位依次进行计算
①按位与 &:有0就是0
int a = 13;
int b = 11;
System.out.println(a & b);//9
②按位或 | :有1就是1
int a = 13;
int b = 11;
System.out.println(a | b);//15
注: 当 & 和 | 的操作数为整数(int, short, long, byte) 的时候, 表示按位运算,当操作数为 boolean 的时候, 表示逻辑运算
③按位取反 ~ :如果该位为 0 则转为 1, 如果该位为 1 则转为 0
int a = 13;
System.out.println(~ a);//-14
④按位异或 ^ :如果两个数字的二进制位相同, 则结果为 0, 相异则结果为 1
int a = 13;
int b = 11;
System.out.println(a ^ b);//6
2.6、移位运算
<< >> >>>
①左移 << :最左侧不要,最右侧补0
int a = 11;
System.out.println(a << 1);//22
System.out.println(a << 2);//44
②右移 >> :最右侧不要,最左侧补符号位(正数补0,负数补1)
int a = 11;
System.out.println(a >> 1);//5
System.out.println(a >> 2);//2
int a = -1;
System.out.println(a >> 1);//-2147483648
③无符号右移 >> :最右侧不要,最左侧补0
int a = -1;
System.out.println(a >>> 1);//2147483647
结论:
①左移 1 位, 相当于原数字 * 2. 左移 N 位, 相当于原数字 * 2 的N次方
②右移 1 位, 相当于原数字 / 2. 右移 N 位, 相当于原数字 / 2 的N次方
③由于计算机计算移位效率高于计算乘除, 当某个代码正好乘除 2 的N次方的时候可以用移位运算代替
⑤移动负数位或者移位位数过大都没有意义
2.7、条件运算符
表达式1 ? 表达式2 : 表达式3
表达式1为true则执行表达式2,否则执行表达式3
这三个表达式都是布尔表达式
也是java中唯一一个三目运算符
boolean a = true ? false : true == true ? true : false;
System.out.println(a);//false
boolean b = false ? false : true == true ? true : false;
System.out.println(b);//true
2.8、运算符的优先级
System.out.println(2 + 3 * 5);//17
结果为17,说明先运算3*5,再计算+2的值
System.out.println(10 < 20 && 20 < 30);//true
结果为true,说明先运算10<20和20<30,再运算&&
运算符之间存在优先级,不必死记硬背,在存在歧义的地方可以加括号提升优先级
System.out.println((2 + 3) * 5);//25
括号提升优先级从而先计算2+3,在计算*5的值