# 第 02 章:随堂复习与企业真题(变量与运算符)
# 一、随堂复习
# 1.1 关键字、保留字
关键字:被 Java 赋予特殊含义的字符串。
- 官方规范中有 50 个关键字
- true、false、null 虽然不是关键字,但是可以当做关键字来看待。
保留字:goto 、 const
# 1.2 标识符
- 标识符:凡是可以自己命名的地方,都是标识符。
- 比如:类名、变量名、方法名、接口名、包名、常量名等
- 记住:标识符命名的规则(必须要遵守的,否则编译不通过)
> 由26个英文字母大小写,0-9 ,_或 $ 组成
> 数字不可以开头。
> 不可以使用关键字和保留字,但能包含关键字和保留字。
> Java中严格区分大小写,长度无限制。
> 标识符不能包含空格。
- 记住:标识符命名的规范(建议遵守。如果不遵守,编译和运行都能正常执行。只是容易被人鄙视)
> 包名:多单词组成时所有字母都小写:xxxyyyzzz。
例如:java.lang、com.atguigu.bean
> 类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz
例如:HelloWorld,String,System等
> 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
例如:age,name,bookName,main,binarySearch,getName
> 常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ
例如:MAX_VALUE,PI,DEFAULT_CAPACITY
- “见名知意”
class IdentifierTest{ | |
public static void main(String[] args){ | |
int abc = 12; | |
int age = 12; //age : 标识符 | |
char gender = '男'; | |
char c1 = '女'; | |
// 不推荐的写法 | |
//int myage = 12; | |
//System.out.println(myage); | |
int myAge = 12; | |
} | |
public static void main1(String[] args){ | |
} | |
} | |
class _a$bc{ | |
} | |
/* | |
class 1abc{ | |
} | |
*/ | |
class Public{ | |
} | |
class publicstatic{ | |
} | |
class BiaoShiFuTest{ | |
} |
# 1.3 变量的基本使用(重点)
- 变量的理解:内存中的一个存储区域,该区域的数据可以在同一类型范围内不断变化
- 变量的构成包含三个要素:数据类型、变量名、存储的值
- Java 中变量声明的格式:数据类型 变量名 = 变量值
class VariableTest { | |
public static void main(String[] args) { | |
// 定义变量的方式 1: | |
char gender; // 过程 1:变量的声明 | |
gender = '男'; // 过程 2:变量的赋值(或初始化) | |
gender = '女'; | |
// 定义变量的方式 2:声明与初始化合并 | |
int age = 10; | |
System.out.println(age); | |
System.out.println("age = " + age); | |
System.out.println("gender = " + gender); | |
// 在同一个作用域内,不能声明两个同名的变量 | |
//char gender = ' 女 '; | |
gender = '男'; | |
// 由于 number 前没有声明类型,即当前 number 变量没有提前定义。所以编译不通过。 | |
//number = 10; | |
byte b1 = 127; | |
//b1 超出了 byte 的范围,编译不通过。 | |
//b1 = 128; | |
} | |
public static void main123(String[] args) { | |
//System.out.println("gender = " + gender); | |
char gender = '女'; | |
} | |
} |
说明:
- 定义变量时,变量名要遵循标识符命名的规则和规范。
- 说明:
① 变量都有其作用域。变量只在作用域内是有效的,出了作用域就失效了。
② 在同一个作用域内,不能声明两个同名的变量
③ 定义好变量以后,就可以通过变量名的方式对变量进行调用和运算。
④ 变量值在赋值时,必须满足变量的数据类型,并且在数据类型有效的范围内变化。
# 1.4 基本数据类型变量的使用(重点)
1、Java 中的变量按照数据类型来分类:
基本数据类型(8种):
整型:byte \ short \ int \ long
浮点型:float \ double
字符型:char
布尔型:boolean
引用数据类型:
类(class)
数组(array)
接口(interface)
枚举(enum)
注解(annotation)
记录(record)
测试整型和浮点型:
/* | |
测试整型和浮点型变量的使用 | |
*/ | |
class VariableTest1 { | |
public static void main(String[] args) { | |
//1. 测试整型变量的使用 | |
//byte (1 字节 = 8bit) \ short (2 字节) \ int (4 字节) \ long (8 字节) | |
byte b1 = 12; | |
byte b2 = 127; | |
// 编译不通过。因为超出了 byte 的存储范围 | |
//byte b3 = 128; | |
short s1 = 1234; | |
int i1 = 123234123; | |
//① 声明 long 类型变量时,需要提供后缀。后缀为 'l' 或 'L' | |
long l1 = 123123123L; | |
//② 开发中,大家定义整型变量时,没有特殊情况的话,通常都声明为 int 类型。 | |
//2. 测试浮点类型变量的使用 | |
//float \ double | |
double d1 = 12.3; | |
//① 声明 long 类型变量时,需要提供后缀。后缀为 'f' 或 'F' | |
float f1 = 12.3f; | |
System.out.println("f1 = " + f1); | |
//② 开发中,大家定义浮点型变量时,没有特殊情况的话,通常都声明为 double 类型,因为精度更高。 | |
//③ float 类型表数范围要大于 long 类型的表数范围。但是精度不高。 | |
// 测试浮点型变量的精度 | |
// 结论:通过测试发现浮点型变量的精度不高。如果在开发中,需要极高的精度,需要使用 BigDecimal 类替换浮点型变量。 | |
// 测试 1 | |
System.out.println(0.1 + 0.2); | |
// 测试 2: | |
float ff1 = 123123123f; | |
float ff2 = ff1 + 1; | |
System.out.println(ff1); | |
System.out.println(ff2); | |
System.out.println(ff1 == ff2); | |
} | |
} |
测试字符型和布尔型:
/* | |
测试字符类型和布尔类型的使用 | |
*/ | |
class VariableTest2 { | |
public static void main(String[] args) { | |
//1. 字符类型:char (2 字节) | |
// 表示形式 1:使用一对 '' 表示,内部有且仅有一个字符 | |
char c1 = 'a'; | |
char c2 = '中'; | |
char c3 = '1'; | |
char c4 = '%'; | |
char c5 = 'γ'; | |
// 编译不通过 | |
//char c6 = ''; | |
//char c7 = 'ab'; | |
// 表示形式 2:直接使用 Unicode 值来表示字符型常量。 | |
char c8 = '\u0036'; | |
System.out.println(c8); | |
// 表示形式 3:使用转义字符 | |
char c9 = '\n'; | |
char c10 = '\t'; | |
System.out.println("hello" + c10 + "world"); | |
// 表示形式 4:使用具体字符对应的数值(比如 ASCII 码) | |
char c11 = 97; | |
System.out.println(c11);//a | |
char c12 = '1'; | |
char c13 = 1; | |
//2. 布尔类型:boolean | |
//① 只有两个取值:true 、 false | |
boolean bo1 = true; | |
boolean bo2 = false; | |
// 编译不通过 | |
//boolean bo3 = 0; | |
//② 常使用在流程控制语句中。比如:条件判断、循环结构等 | |
boolean isMarried = true; | |
if(isMarried){ | |
System.out.println("很遗憾,不能参加单身派对了"); | |
}else{ | |
System.out.println("可以多谈几个女朋友或男朋友"); | |
} | |
//③ 了解:我们不谈 boolean 类型占用的空间大小。但是,真正在内存中分配的话,使用的是 4 个字节。 | |
} | |
} |
# 1.5 基本数据类型变量间的运算规则(重点)
# 1.5.1 自动类型提升
/* | |
测试基本数据类型变量间的运算规则。 | |
1. 这里提到可以做运算的基本数据类型有 7 种,不包含 boolean 类型。 | |
2. 运算规则包括: | |
① 自动类型提升 | |
② 强制类型转换 | |
3. 此 VariableTest3.java 用来测试自动类型提升 | |
规则:当容量小的变量与容量大的变量做运算时,结果自动转换为容量大的数据类型。 | |
byte 、short 、char ---> int ---> long ---> float ---> double | |
特别的:byte、short、char 类型的变量之间做运算,结果为 int 类型。 | |
说明:此时的容量小或大,并非指占用的内存空间的大小,而是指表示数据的范围的大小。 | |
long (8 字节) 、 float (4 字节) | |
*/ | |
class VariableTest3 { | |
public static void main(String[] args) { | |
int i1 = 10; | |
int i2 = i1; | |
long l1 = i1; | |
float f1 = l1; | |
byte b1 = 12; | |
int i3 = b1 + i1; | |
// 编译不通过 | |
//byte b2 = b1 + i1; | |
//********************************************** | |
// 特殊的情况 1:byte、short 之间做运算 | |
byte b3 = 12; | |
short s1 = 10; | |
// 编译不通过 | |
//short s2 = b3 + s1; | |
i3 = b3 + s1; | |
byte b4 = 10; | |
// 编译不通过 | |
//byte b5 = b3 + b4; | |
// 特殊的情况 2:char | |
char c1 = 'a'; | |
// 编译不通过 | |
//char c2 = c1 + b3; | |
int i4 = c1 + b3; | |
//********************************************** | |
// 练习 1: | |
long l2 = 123L; | |
long l3 = 123; // 理解为:自动类型提升 (int--->long) | |
//long l4 = 123123123123; //123123123123 理解为 int 类型,因为超出了 int 范围,所以报错。 | |
long l5 = 123123123123L;// 此时的 123123123123L 就是使用 8 个字节存储的 long 类型的值 | |
// 练习 2: | |
float f2 = 12.3F; | |
// 编译不通过 | |
//float f3 = 12.3; // 不满足自动类型提升的规则(double --> float)。所以报错 | |
// 练习 3: | |
// 规定 1:整型常量,规定是 int 类型。 | |
byte b5 = 10; | |
//byte b6 = b5 + 1; | |
int ii1 = b5 + 1; | |
// 规定 2:浮点型常量,规定是 double 类型。 | |
double dd1 = b5 + 12.3; | |
// 练习 4:说明为什么不允许变量名是数字开头的。为了 “自洽” | |
/* | |
int 123L = 12; | |
long l6 = 123L; | |
*/ | |
} | |
} |
# 1.5.2 强制类型转换
/* | |
此 VariableTest4.java 用来测试强制类型转换 | |
规则: | |
1. 如果需要将容量大的变量的类型转换为容量小的变量的类型,需要使用强制类型转换 | |
2. 强制类型转换需要使用强转符:()。在 () 内指明要转换为的数据类型。 | |
3. 强制类型转换过程中,可能导致精度损失。 | |
*/ | |
class VariableTest4 { | |
public static void main(String[] args) { | |
double d1 = 12;// 自动类型提升 | |
// 编译失败 | |
//int i1 = d1; | |
int i2 = (int)d1; | |
System.out.println(i2); | |
long l1 = 123; | |
// 编译失败 | |
//short s1 = l1; | |
short s2 = (short)l1; | |
System.out.println(s2); | |
// 练习 | |
int i3 = 12; | |
float f1 = i3;// 自动类型提升 | |
System.out.println(f1); //12.0 | |
float f2 = (float)i3; // 编译可以通过。只不过可以省略 () 而已。 | |
// 精度损失的例子 1: | |
double d2 = 12.9; | |
int i4 = (int)d2; | |
System.out.println(i4); | |
// 精度损失的例子 2: | |
int i5 = 128; | |
byte b1 = (byte)i5; | |
System.out.println(b1); //-128 | |
// 实际开发举例: | |
byte b2 = 12; | |
method(b2); | |
long l2 = 12L; | |
// 编译不通过 | |
//method(l2); | |
method((int)l2); | |
} | |
public static void method(int num){ //int num = b2; 自动类型提升 | |
System.out.println("num = " + num); | |
} | |
} |
# 1.6 String 类的使用、与基本数据类型变量间的运算(重点)
- String 的认识:字符串。使用一对 "" 表示,内部包含 0 个、1 个或多个字符。
- String 与 8 种基本数据类型变量间的运算:+。运算的结果是 String 类型。
/* | |
基本数据类型与 String 的运算 | |
一、关于 String 的理解 | |
1. String 类,属于引用数据类型,俗称字符串。 | |
2. String 类型的变量,可以使用一对 "" 的方式进行赋值。 | |
3. String 声明的字符串内部,可以包含 0 个,1 个或多个字符。 | |
二、String 与基本数据类型变量间的运算 | |
1. 这里的基本数据类型包括 boolean 在内的 8 种。 | |
2. String 与基本数据类型变量间只能做连接运算,使用 "+" 表示。 | |
3. 运算的结果是 String 类型。 | |
*/ | |
class StringTest { | |
public static void main(String[] args) { | |
String str1 = "Hello World!"; | |
System.out.println("str1"); | |
System.out.println(str1); | |
String str2 = ""; | |
String str3 = "a";//char c1 = 'a'; | |
// 测试连接运算 | |
int num1 = 10; | |
boolean b1 = true; | |
String str4 = "hello"; | |
System.out.println(str4 + b1); | |
String str5 = str4 + b1; | |
String str6 = str4 + b1 + num1; | |
System.out.println(str6);//hellotrue10 | |
// 思考:如下的声明编译能通过吗?不能 | |
//String str7 = b1 + num1 + str4; | |
// 如何将 String 类型的变量转换为基本数据类型? | |
String str8 = "abc";// 不能考虑转换为基本数据类型的。 | |
int num2 = 10; | |
String str9 = num2 + ""; //"10" | |
// 编译不通过 | |
//int num3 = (int)str9; | |
// 如何实现呢?使用 Integer 类。暂时大家了解。 | |
int num3 = Integer.parseInt(str9); | |
System.out.println(num3 + 1); | |
} | |
} |
- 练习 1
/* | |
要求填写自己的姓名、年龄、性别、体重、婚姻状况(已婚用 true 表示,单身用 false 表示)、联系方式等等。 | |
*/ | |
class StringExer { | |
public static void main(String[] args) { | |
String name = "李进"; | |
int age = 24; | |
char gender = '男'; | |
double weight = 130.5; | |
boolean isMarried = false; | |
String phoneNumber = "13012341234"; | |
String info = "name = " + name + ",age = " + age + ",gender = " + gender + ",weight = " + | |
weight + ",isMarried = " + isMarried + ",phoneNumber = " + phoneNumber; | |
System.out.println(info); | |
} | |
} |
- 练习 2
class StringExer1 { | |
public static void main(String[] args) { | |
// 练习 1: | |
//String str1 = 4; // 判断对错:no | |
String str2 = 3.5f + ""; // 判断 str2 对错:yes | |
System.out.println(str2); // 输出:3.5 | |
System.out .println(3+4+"Hello!"); // 输出:7Hello! | |
System.out.println("Hello!"+3+4); // 输出:Hello!34 | |
System.out.println('a'+1+"Hello!"); // 输出:98Hello! | |
System.out.println("Hello"+'a'+1); // 输出:Helloa1 | |
// 练习 2: | |
System.out.println("* *"); // 输出:* * | |
System.out.println("*\t*"); // 输出:* * | |
System.out.println("*" + "\t" + "*"); // 输出:* * | |
System.out.println('*' + "\t" + "*"); // 输出:* * | |
System.out.println('*' + '\t' + "*"); // 输出:51* | |
System.out.println('*' + "\t" + '*'); // 输出:* * | |
System.out.println("*" + '\t' + '*'); // 输出:* * | |
System.out.println('*' + '\t' + '*'); // 输出:93 | |
} | |
} |
# 1.7 常识:进制的认识
- 熟悉:二进制(以 0B、0b 开头)、十进制、八进制(以 0 开头)、十六进制(以 0x 或 0X 开头)的声明方式。
- 二进制的理解
- 正数:原码、反码、补码三码合一。
- 负数:原码、反码、补码不相同。了解三者之间的关系。
- 计算机的底层是以
补码
的方式存储数据的。
- 熟悉:二进制与十进制之间的转换
- 了解:二进制与八进制、十六进制间的转换
# 1.8 运算符(较常用的是重点)
# 1.8.1 算术运算符
/* | |
测试运算符的使用 1:算术运算符的使用 | |
1. + - + - * / % (前)++ (后)++ (前)-- (后)-- + | |
*/ | |
class AriTest { | |
public static void main(String[] args) { | |
//******************************* | |
// 除法: / | |
int m1 = 12; | |
int n1 = 5; | |
int k1 = m1 / n1; | |
System.out.println(k1);//2 | |
System.out.println(m1 / n1 * n1);//10 | |
//******************************* | |
// 取模(或取余): % | |
int i1 = 12; | |
int j1 = 5; | |
System.out.println(i1 % j1); //2 | |
// 开发中,经常用来判断某个数 num1 能整除另外一个数 num2。 num1 % num2 == 0 | |
// 比如:判断 num1 是否是偶数: num1 % 2 == 0 | |
// 结论:取模以后,结果与被模数的符号相同 | |
int i2 = -12; | |
int j2 = 5; | |
System.out.println(i2 % j2); //-2 | |
int i3 = 12; | |
int j3 = -5; | |
System.out.println(i3 % j3); //2 | |
int i4 = -12; | |
int j4 = -5; | |
System.out.println(i4 % j4); //-2 | |
//******************************* | |
//(前)++ : 先自增 1,再运算 | |
//(后)++ : 先运算,后自增 1 | |
int a1 = 10; | |
int b1 = ++a1; | |
System.out.println("a1 = " + a1 + ",b1 = " + b1); //a1 = 11,b1 = 11 | |
int a2 = 10; | |
int b2 = a2++; | |
System.out.println("a2 = " + a2 + ",b2 = " + b2); //a2 = 11,b2 = 10 | |
// 练习 1: | |
int i = 10; | |
//i++; | |
++i; | |
System.out.println("i = " + i);//11 | |
// 练习 2: | |
short s1 = 10; | |
// 方式 1: | |
// 编译不通过 | |
//s1 = s1 + 1; | |
//s1 = (short)(s1 + 1); | |
//System.out.println(s1); | |
// 方式 2: | |
s1++; | |
System.out.println(s1); | |
//******************************* | |
//(前)-- : 先自减 1,再运算 | |
//(后)-- : 先运算,再自减 1 | |
// 略 | |
// 结论:++ 或 -- 运算,不会改变变量的数据类型! | |
//+ : 连接符,只适用于 String 与其他类型的变量间的运算,而且运算的结果也是 String 类型。 | |
} | |
} |
练习 1:
/* | |
随意给出一个三位的整数,打印显示它的个位数,十位数,百位数的值。 | |
格式如下: | |
数字 xxx 的情况如下: | |
个位数: | |
十位数: | |
百位数: | |
例如: | |
数字 153 的情况如下: | |
个位数:3 | |
十位数:5 | |
百位数:1 | |
*/ | |
class AriExer { | |
public static void main(String[] args) { | |
int num = 153; | |
int ge = num % 10; // 个位 | |
int shi = num / 10 % 10; // 十位。或者 int shi = num % 100 / 10 | |
int bai = num / 100; | |
System.out.println("个位是:" + ge); | |
System.out.println("十位是:" + shi); | |
System.out.println("百位是:" + bai); | |
} | |
} |
练习 2:
/* | |
案例 2:为抵抗洪水,战士连续作战 89 小时,编程计算共多少天零多少小时? | |
*/ | |
class AriExer1 { | |
public static void main(String[] args) { | |
int hours = 89; | |
int day = hours / 24; | |
int hour = hours % 24; | |
System.out.println("共奋战了" + day + "天零" + hour + "小时"); | |
// 额外的练习 1: | |
System.out.println("5+5=" + 5 + 5); | |
System.out.println("5+5=" + (5 + 5)); | |
// 额外的练习 2: | |
byte bb1 = 127; | |
bb1++; | |
System.out.println("bb1 = " + bb1); | |
// 额外的练习 3: | |
//int i = 1; | |
//int j = i++ + ++i * i++; | |
//System.out.println("j = " + j);//10 | |
// 额外的练习 4: | |
int i = 2; | |
int j = i++; | |
System.out.println(j); //2 | |
int k = 2; | |
int z = ++k; | |
System.out.println(z);//3 | |
int m = 2; | |
m = m++; | |
System.out.println(m); //2 | |
} | |
} |
# 1.8.2 赋值运算符
/* | |
测试运算符的使用 2:赋值运算符 | |
1. = +=、 -=、*=、 /=、%= | |
2. 说明: | |
① 当 “=” 两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理。 | |
② 支持连续赋值。 | |
③ +=、 -=、*=、 /=、%= 操作,不会改变变量本身的数据类型。 | |
*/ | |
class SetValueTest { | |
public static void main(String[] args) { | |
//*********************************** | |
int i = 5; | |
long l = 10; // 自动类型提升 | |
byte b = (byte)i; // 强制类型转换 | |
// 操作方式 1: | |
int a1 = 10; | |
int b1 = 10; | |
// 操作方式 2:连续赋值 | |
int a2; | |
int b2; | |
// 或合并:int a2,b2; | |
a2 = b2 = 10; | |
System.out.println(a2 + "," + b2); | |
// 操作方式 3: | |
//int a3 = 10; | |
//int b3 = 20; | |
int a3 = 10,b3 = 20; | |
System.out.println(a3 + "," + b3); | |
//*********************************** | |
// 说明 += 的使用 | |
int m1 = 10; | |
m1 += 5; // 类似于 m1 = m1 + 5; | |
System.out.println(m1); | |
byte by1 = 10; | |
by1 += 5; //by1 = by1 + 5 操作会编译报错。应该写为: by1 = (byte)(by1 + 5); | |
System.out.println(by1); | |
int m2 = 1; | |
m2 *= 0.1; // m2 = (int)(m2 * 0.1) | |
System.out.println(m2); | |
// 练习 1:如何实现变量的值增加 2。 | |
// 方式 1: | |
int n1 = 10; | |
n1 = n1 + 2; | |
// 方式 2:推荐 | |
int n2 = 10; | |
n2 += 2; | |
// 错误的写法: | |
//int n3 = 10; | |
//n3++++; | |
// 练习 2:如何实现变量的值增加 1。 | |
// 方式 1: | |
int i1 = 10; | |
i1 = i1 + 1; | |
// 方式 2: | |
int i2 = 10; | |
i2 += 1; | |
// 方式 3:推荐 | |
int i3 = 10; | |
i3++; //++i3; | |
} | |
} |
# 1.8.3 比较运算符
/* | |
测试运算符的使用 3:比较运算符 | |
1. == != > < >= <= instanceof | |
2. 说明 | |
① instanceof 在面向对象的多态性的位置讲解。 | |
② == != > < >= <= 适用于基本数据类型。(细节:> < >= <= 不适用于 boolean 类型) | |
运算的结果为 boolean 类型。 | |
③ 了解: == != 可以适用于引用数据类型 | |
④ 区分:== 与 = | |
*/ | |
class CompareTest { | |
public static void main(String[] args) { | |
int m1 = 10; | |
int m2 = 20; | |
boolean compare1 = m1 > m2; | |
System.out.println(compare1); | |
int n1 = 10; | |
int n2 = 20; | |
System.out.println(n1 == n2);//false | |
System.out.println(n1 = n2);//20 | |
boolean b1 = false; | |
boolean b2 = true; | |
System.out.println(b1 == b2);//false | |
System.out.println(b1 = b2);//true | |
} | |
} |
# 1.8.4 逻辑运算符
/* | |
测试运算符的使用 4:逻辑运算符 | |
1. & && | || ! ^ | |
2. 说明: | |
① 逻辑运算符针对的都是 boolean 类型的变量进行的操作 | |
② 逻辑运算符运算的结果也是 boolean 类型。 | |
③ 逻辑运算符常使用条件判断结构、循环结构中 | |
*/ | |
class LogicTest { | |
public static void main(String[] args) { | |
/* | |
区分:& 和 && | |
1、相同点:两个符号表达的都是 "且" 的关系。只有当符号左右两边的类型值均为 true 时,结果才为 true。 | |
2、执行过程: | |
1)如果符号左边是 true,则 & amp; 、&& 都会执行符号右边的操作 | |
2)如果符号左边是 false,则 & 会继续执行符号右边的操作 | |
&& 不会执行符号右边的操作 | |
3、开发中,我们推荐使用 & amp;& | |
*/ | |
boolean b1 = true; | |
b1 = false; | |
int num1 = 10; | |
if(b1 & (num1++ > 0)){ | |
System.out.println("床前明月光"); | |
}else{ | |
System.out.println("我叫郭德纲"); | |
} | |
System.out.println("num1 = " + num1); | |
// | |
boolean b2 = true; | |
b2 = false; | |
int num2 = 10; | |
if(b2 && (num2++ > 0)){ | |
System.out.println("床前明月光"); | |
}else{ | |
System.out.println("我叫郭德纲"); | |
} | |
System.out.println("num2 = " + num2); | |
//******************************************** | |
/* | |
区分:| 和 || | |
1、相同点:两个符号表达的都是 "或" 的关系。只要符号两边存在 true 的情况,结果就为 true. | |
2、执行过程: | |
1)如果符号左边是 false,则 | 、|| 都会执行符号右边的操作 | |
2)如果符号左边是 true,则 | 会继续执行符号右边的操作 | |
|| 不会执行符号右边的操作 | |
3、开发中,我们推荐使用 || | |
*/ | |
boolean b3 = false; | |
b3 = true; | |
int num3 = 10; | |
if(b3 | (num3++ > 0)){ | |
System.out.println("床前明月光"); | |
}else{ | |
System.out.println("我叫郭德纲"); | |
} | |
System.out.println("num3 = " + num3); | |
// | |
boolean b4 = false; | |
b4 = true; | |
int num4 = 10; | |
if(b4 || (num4++ > 0)){ | |
System.out.println("床前明月光"); | |
}else{ | |
System.out.println("我叫郭德纲"); | |
} | |
System.out.println("num4 = " + num4); | |
} | |
} |
练习:
/* | |
1. 定义类 LogicExer | |
2. 定义 main 方法 | |
3. 定义一个 int 类型变量 a, 变量 b, 都赋值为 20 | |
4. 定义 boolean 类型变量 bo1 , 判断 ++a 是否被 3 整除,并且 a++ 是否被 7 整除,将结果赋值给 bo1 | |
5. 输出 a 的值,bo1 的值 | |
6. 定义 boolean 类型变量 bo2 , 判断 b++ 是否被 3 整除,并且 ++b 是否被 7 整除,将结果赋值给 bo2 | |
7. 输出 b 的值,bo2 的值 | |
*/ | |
class LogicExer { | |
public static void main(String[] args) { | |
int a,b; | |
a = b = 20; | |
boolean bo1 = (++a % 3 == 0) && (a++ % 7 == 0); | |
System.out.println("a = " + a + ",bo1 = " + bo1); | |
boolean bo2 = (b++ % 3 == 0) && (++b % 7 == 0); | |
System.out.println("b = " + b + ",bo2 = " + bo2); | |
} | |
} |
# 1.8.5 位运算符 (了解)
/* | |
测试运算符的使用 5:位运算符 | |
1. << >> >>> & | ^ ~ | |
2. 说明: | |
① << >> >>> & | ^ ~ :针对数值类型的变量或常量进行运算,运算的结果也是数值 | |
② | |
<< : 在一定范围内,每向左移动一位,结果就在原有的基础上 * 2。(对于正数、负数都适用) | |
>> : 在一定范围内,每向右移动一位,结果就在原有的基础上 / 2。(对于正数、负数都适用) | |
3. 面试题:高效的方式计算 2 * 8 ? | |
2 << 3 或 8 << 1 | |
*/ | |
class BitTest { | |
public static void main(String[] args) { | |
int num1 = 7; | |
System.out.println("num1 << 1 : " + (num1 << 1)); | |
System.out.println("num1 << 2 : " + (num1 << 2)); | |
System.out.println("num1 << 3 : " + (num1 << 3)); | |
System.out.println("num1 << 28 : " + (num1 << 28)); | |
System.out.println("num1 << 29 : " + (num1 << 29));// 过犹不及 | |
int num2 = -7; | |
System.out.println("num2 << 1 : " + (num2 << 1)); | |
System.out.println("num2 << 2 : " + (num2 << 2)); | |
System.out.println("num2 << 3 : " + (num2 << 3)); | |
System.out.println(~9); | |
System.out.println(~-10); | |
} | |
} |
练习:
/* | |
案例 2:如何交换两个 int 型变量的值?String 呢? | |
*/ | |
class BitExer { | |
public static void main(String[] args) { | |
int m = 10; | |
int n = 20; | |
System.out.println("m = " + m + ",n = " + n); | |
// 交换两个变量的值 | |
// 方式 1:声明一个临时变量。(推荐) | |
//int temp = m; | |
//m = n; | |
//n = temp; | |
// 方式 2:优点:不需要定义临时变量。 缺点:难、适用性差(不适用于非数值类型)、可能超出 int 的范围 | |
//m = m + n; //30 = 10 + 20; | |
//n = m - n; //10 = 30 - 20; | |
//m = m - n; //20 = 30 - 10; | |
// 方式 3:优点:不需要定义临时变量。 缺点:真难、适用性差(不适用于非数值类型) | |
m = m ^ n; | |
n = m ^ n;//(m ^ n) ^ n ---> m | |
m = m ^ n; | |
System.out.println("m = " + m + ",n = " + n); | |
} | |
} |
# 1.8.6 条件运算符
/* | |
测试运算符的使用 6:条件运算符 | |
1. (条件表达式)? 表达式 1 : 表达式 2 | |
2. 说明: | |
① 条件表达式的结果是 boolean 类型。 | |
② 如果条件表达式的结果是 true,则执行表达式 1。否则,执行表达式 2。 | |
③ 表达式 1 和 表达式 2 需要是相同的类型或能兼容的类型。 | |
④ 开发中,凡是可以使用条件运算符的位置,都可以改写为 if-else。 | |
反之,能使用 if-else 结构,不一定能改写为条件运算符。 | |
建议,在二者都能使用的情况下,推荐使用条件运算符。因为执行效率稍高。 | |
*/ | |
class ConditionTest { | |
public static void main(String[] args) { | |
String info = (2 > 10)? "表达式1" : "表达式2"; | |
System.out.println(info); | |
double result = (2 > 1)? 1 : 2.0; | |
System.out.println(result); | |
// 练习 1:获取两个整数的较大值 | |
int m = 10; | |
int n = 20; | |
int max = (m > n)? m : n; | |
System.out.println("较大值为:" + max); | |
// 练习 2:获取三个整数的最大值 | |
int i = 20; | |
int j = 30; | |
int k = 23; | |
int tempMax = (i > j)? i : j; | |
int finalMax = (tempMax > k)? tempMax : k; | |
System.out.println(finalMax); | |
// 合并以后的写法:不推荐 | |
int finalMax1 = (((i > j)? i : j) > k)? ((i > j)? i : j) : k; | |
System.out.println(finalMax1); | |
} | |
} |
# 1.8.7 运算符的优先级
- 如果想体现优先级比较高,使用 ()
- 我们在编写一行执行语句时,不要出现太多的运算符。
# 二、企业真题
# 1. 高效的方式计算 2 * 8 的值 (文 ** 辉、轮 * 科技)
使用 << 。例如:2<<3 或 8<<1
# 2. & 和 && 的区别?(恒 * 电子、* 度)
略,后者短路
# 3. Java 中的基本类型有哪些?String 是最基本的数据类型吗?(恒 * 电子)
四类八种。
String 不是,属于引用数据类型。
# 4. Java 中的基本数据类型包括哪些?(* 米)
类似问题:
> Java的基础数据类型有哪些?String是吗?(贝壳)
略
# 5. Java 开发中计算金额时使用什么数据类型?(5 * 到家)
不能使用 float 或 double,因为精度不高。
使用BigDecimal 类替换,可以实现任意精度的数据的运算。
# 6. char 型变量中能不能存储一个中文汉字,为什么?(* 通快递)
可以的。char c1 = ' 中 ';
char c2 = 'a'。
因为 char 使用的是 unicode 字符集,包含了世界范围的所有的字符。
# 7. 代码分析 (君 * 科技、新 * 陆)
short s1=1; | |
s1=s1+1; // 有什么错? = 右边是 int 类型。需要强转 |
short s1=1; | |
s1+=1; // 有什么错?没错 |
# 8. int i=0; i=i++ 执行这两句化后变量 i 的值为(* 软)
0。
# 9. 如何将两个变量的值互换(北京 * 彩、中外 * 译咨询)
String s1 = "abc"; | |
String s2 = "123"; | |
String temp = s1; | |
s1 = s2; | |
s2 = temp; |
# 10. boolean 占几个字节(阿 ** 巴)
编译时不谈占几个字节。
但是JVM在给boolean类型分配内存空间时,boolean类型的变量占据一个槽位(slot,等于4个字节)。
细节:true:1 false:0
>拓展:在内存中,byte\short\char\boolean\int\float : 占用1个slot
double\long :占用2个slot
# 11. 为什么 Java 中 0.1 + 0.2 结果不是 0.3?(字 * 跳动)
在代码中测试 0.1 + 0.2,你会惊讶的发现,结果不是 0.3,而是 0.3000……4。这是为什么?
几乎所有现代的编程语言都会遇到上述问题,包括 JavaScript、Ruby、Python、Swift 和 Go 等。引发这个问题的原因是,它们都采用了 IEEE 754标准
。
IEEE 是指 “电气与电子工程师协会”,其在 1985 年发布了一个 IEEE 754 计算标准,根据这个标准,小数的二进制表达能够有最大的精度上限提升。但无论如何,物理边界是突破不了的,它仍然 **
不能实现“每一个十进制小数,都对应一个二进制小数”
**。正因如此,产生了 0.1 + 0.2 不等于 0.3 的问题。
具体的:
整数变为二进制,能够做到 “每个十进制整数都有对应的二进制数”,比如数字 3,二进制就是 11;再比如,数字 43 就是二进制 101011,这个毫无争议。
对于小数,并不能做到 “每个小数都有对应的二进制数字”。举例来说,二进制小数 0.0001 表示十进制数 0.0625 (至于它是如何计算的,不用深究);二进制小数 0.0010 表示十进制数 0.125;二进制小数 0.0011 表示十进制数 0.1875。看,对于四位的二进制小数,二进制小数虽然是连贯的,但是十进制小数却不是连贯的。比如,你无法用四位二进制小数的形式表示 0.125 ~ 0.1875 之间的十进制小数。
所以在编程中,遇见小数判断相等情况,比如开发银行、交易等系统,可以采用 四舍五入
或者 “ 同乘同除
” 等方式进行验证,避免上述问题。