第2章、基本语法(上):变量和运算符
一、基本语法(上):变量和运算符
1、Java基础知识图解
2、关键字与保留字
(1)关键字(keyword)的定义和特点
- 定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词)
- 特点:关键字中所有字母都为小写
- 官方地址:
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
(2)保留字(reserved word)
Java保留字:现有Java版本尚未使用,但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留字 goto 、const
3、标识符(Identifier)
- (1)标识符:
- Java 对各种变量、方法和类等要素命名时使用的字符序列称为标识符
- 技巧:凡是自己可以起名字的地方都叫标识符。
- (2)定义合法标识符规则:
- 由26个英文字母大小写,0-9 ,_或 $ 组成
- 数字不可以开头。
- 不可以使用关键字和保留字,但能包含关键字和保留字。
- Java中严格区分大小写,长度无限制。
- 标识符不能包含空格。
4、Java中的名称命名规范
- (1)Java中的名称命名规范:
- 包名:多单词组成时所有字母都小写:xxxyyyzzz
- 类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz
- 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
- 常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ
- (2)注意1:在起名字时,为了提高阅读性,要尽量有意义,“见名知意”。
- (3)注意2:java采用unicode字符集,因此标识符也可以使用汉字声明,但是不建议使用。
5、变量
(1)概念
-
(1)变量的概念:
- 内存中的一个存储区域
- 该区域的数据可以在同一类型范围内不断变化
- 变量是程序中最基本的存储单元。包含变量类型、变量名和存储的值
-
(2)变量的作用:
- 用于在内存中保存数据
-
(3)使用变量注意:
- Java中每个变量必须先声明,后使用
- 使用变量名来访问这块区域的数据
- 变量的作用域:其定义所在的一对{ }内
- 变量只有在其作用域内才有效
- 同一个作用域内,不能定义重名的变量
-
(4)声明变量
- 语法:<数据类型> <变量名称>
- 例如:int var;
-
(5)变量的赋值
- 语法:<变量名称> = <值>
- 例如:var = 10;
-
(6)声明和赋值变量
- 语法: <数据类型> <变量名> = <初始化值>
- 例如:int var = 10;
-
(7)示例
/**
* @author: huxingxin
* @date: 2022/11/11 10:31:13
* @description: 变量的定义和注意点
*
* 变量的使用
* 1、Java定义变量的格式: 数据类型 变量名 = 变量值
* 2、说明:
* >变量必须先声明,后使用。
* >变量都定义在其作用域内。在作用域内它是有效的,出了作用域就失效了。
* >同一个作用域内,不可以声明两个同名的变量。
*
*/
public class VariableTest {
public static void main(String[] args) {
//变量的定义
int age = 27;
System.out.printf("age: %s\n", age);
//编译错误:使用number之前并未定义过number
// System.out.println(number);
//变量的声明
int number;
//编译错误:使用number之前并未赋值过number
//System.out.println(number);
//变量的赋值
number = 100;
System.out.printf("number: %s\n", number);
//编译错误:变量id不在作用域内 {}
//System.out.println(id);
//编译错误:变量名重复了
//int number;
}
public void method(){
int id = 1;
}
}
//编译错误:变量名重复了
//class VariableTest{ }
(2)变量的分类
(1)按数据类型:对于每一种数据都定义了明确的具体数据类型(强类型语言),在内存中分配了不同大小的内存空间。
(2)按声明的位置的不同
- 在方法体外,类体内声明的变量称为成员变量。
- 在方法体内部声明的变量称为局部变量。
- 注意:二者在初始化值方面的异同:
- 同:都有生命周期 异:局部变量除形参外,需显式初始化。
(3)整数类型: byte、short、int、long
- Java各整数类型有固定的表数范围和字段长度,不受具体OS的影响,以保java程序的可移植性。
- java的整型常量默认为 int 型,声明long型常量须后加
‘l’
或‘L’
- java程序中变量通常声明为int型,除非不足以表示较大的数,才使用long
1MB = 1024KB 1KB= 1024B B= byte(字节) 1byte = 8bit(位)
bit: 计算机中的最小存储单位。byte:计算机中基本存储单元。
示例:
public class VariableTest {
public static void main(String[] args) {
//1、整型 byte(1个字节 = 8bit) short int long
// 通常,定义整型变量时,用int型。
//byte (-128 ~ 127)
byte b1 = 127;
System.out.printf("b1: %s\n", b1);
//b1 = 128;//编译不通过
//short
short s1 = 888;
System.out.printf("s1: %s\n", s1);
//int
int i1 = 888888;
System.out.printf("i1: %s\n", i1);
//long 声明long型变量,必须以‘l’ 或者 ‘L’结尾。
long l1 = 8888888L;
System.out.printf("l1: %s\n", l1);
}
}
(4)浮点类型:float、double
- 与整数类型类似,Java 浮点类型也有固定的表数范围和字段长度,不受具体操作系统的影响。
- 浮点型常量有两种表示形式:
- 十进制数形式:如:
5.12 512.0f .512 (必须有小数点)
- 科学计数法形式:如:
5.12e2 512E2 100E-2
- 十进制数形式:如:
- float:单精度,尾数可以精确到7位有效数字。很多情况下,精度很难满足需求。
- double:双精度,精度是float的两倍。通常采用此类型。
Java 的浮点型常量默认为double型,声明float型常量,须后加‘f’或‘F’。
示例:
public class VariableTest {
public static void main(String[] args) {
//2、浮点型: float(4字节) double(8字节)
// 浮点型:表示带小数点的数字
// float表示数值的范围比long还大
// 通常,定义浮点型变量时,用double型。
double d1 = 123.4;
System.out.printf("d1: %s\n", d1);
//定义float类型变量时,变量要以 ‘f’ 或者 ‘F’ 结尾。
float f1 = 12.3f;
System.out.printf("f1: %s\n", f1);
}
}
(5)字符类型:char
- char 型数据用来表示通常意义上“字符”(2字节)
- Java中的所有字符都使用Unicode编码,故一个字符可以存储一个字母,一个汉字,或其他书面语的一个字符。
- 字符型变量的三种表现形式:
- 字符常量是用单引号(‘ ’)括起来的单个字符。例如:
char c1 = 'a'; char c2 = '中'; char c3 = '9';
- Java中还允许使用转义字符‘\’来将其后的字符转变为特殊字符型常量。
- 例如:
char c3 = ‘\n’; // '\n'表示换行符
- 例如:
- 直接使用 Unicode 值来表示字符型常量:
‘\uXXXX’
。其中,XXXX代表一个十六进制整数。如:\u000a
表示\n
。
- 字符常量是用单引号(‘ ’)括起来的单个字符。例如:
- char类型是可以进行运算的。因为它都对应有
Unicode
码。
示例:
public class VariableTest {
public static void main(String[] args) {
//3、字符型 char(1字符 = 2字节)
// 定义char型变量,通常使用一对 ''
char c1 = 'a';
//c1 = 'AB'; //编译不通过
char c2 = '我';
System.out.printf("c1: %s\n", c1);
System.out.printf("c2: %s\n", c2);
//表示方式:1 声明一个字符 2 转义字符 3 直接使用Unicode值来表示字符型常量
char c3 = '\n';//换行符
char c4 = '\t';//制表符
System.out.printf("%s%s\n", c1, c2);
System.out.printf("%s%s%s\n", c1, c3, c2);
System.out.printf("%s%s%s\n", c1, c4, c2);
//直接使用Unicode值来表示字符型常量
char c5 = '\u0041';
System.out.printf("c5: %s\n", c5);
}
}
了解:ASCII 码
- 在计算机内部,所有数据都使用二进制表示。每一个
二进制
位(bit)有 0 和 1 两种状态,因此 8 个二进制位就可以组合出 256 种状态,这被称为一个字节(byte)。一个字节一共可以用来表示 256 种不同的状态,每一个状态对应一个符号,就是256
个符号,从0000000 到 11111111。 - ASCII码:上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码。ASCII码一共规定了128个字符的编码,比如空格“SPACE”是32(二进制00100000),大写的字母A是65(二进制01000001)。这
128个
符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。 缺点:
- 不能表示所有字符。
- 相同的编码表示的字符不一样:比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel(ג)
了解: Unicode 编码
- 乱码:世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。
- Unicode:一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,使用 Unicode 没有乱码的问题。
- Unicode 的缺点:Unicode 只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储:无法区别 Unicode 和 ASCII:计算机无法区分三个字节表示一个符号还是分别表示三个符号。另外,我们知道,英文字母只用一个字节表示就够了,如果unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储空间来说是极大的浪费。
了解: UTF-8
-
UTF-8 是在互联网上使用最广的一种 Unicode 的实现方式。
-
UTF-8 是一种变长的编码方式。它可以使用 1-6 个字节表示一个符号,根据不同的符号而变化字节长度。
-
UTF-8的编码规则:
- 对于单字节的UTF-8编码,该字节的最高位为0,其余7位用来对字符进行编码(等同于ASCII码)。
- 对于多字节的UTF-8编码,如果编码包含 n 个字节,那么第一个字节的前 n 位为1,第一个字节的第 n+1 位为0,该字节的剩余各位用来对字符进行编码。在第一个字节之后的所有的字节,都是最高两位为"10",其余6位用来对字符进行编码。
(6)布尔类型:boolean
- boolean 类型用来判断逻辑条件,一般用于程序流程控制:
- if条件控制语句;
- while循环控制语句;
- do-while循环控制语句;
- for循环控制语句;
- boolean类型数据只允许取值true和false,无null。
- 不可以使用0或非 0 的整数替代false和true,这点和C语言不同。
- Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达所操作的boolean值,在编译之后都使用java虚拟机中的int数据类型来代替:true用1表示,false用0表示。
示例:
public class VariableTest {
public static void main(String[] args) {
//4、布尔型:boolean
// 只能取两个值之一:true false
// 常常在条件判断 循环结构中使用
boolean bl1 = true;
System.out.printf("bl1: %s\n", bl1);
boolean bl2 = false;
System.out.printf("bl2: %s\n", bl2);
//boolean bl3 = 1; //编译不通过
boolean isMarried = true;
if (isMarried){
System.out.println("很遗憾,不能参加\"单身\"party了");
}else {
System.out.println("可以多找找女朋友");
}
}
}
(7)基本数据类型转换
- 自动类型转换:容量小的类型自动转换为容量大的数据类型。数据类型按容量大小排序为:
- 有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算。
- byte,short,char之间不会相互转换,他们三者在计算时首先转换为int类型。
- boolean类型不能与其它数据类型运算。
- 当把任何基本数据类型的值和字符串(String)进行连接运算时(+),基本数据类型的值将自动转化为字符串(String)类型。
示例:
/**
* @author: huxingxin
* @date: 2022/11/11 20:35:59
* @description:
* 基本数据类型之间的运算规则
* 前提:这里讨论只是7种基本数据类型变量间的运算,不包含boolean类型的。
* 1、自动类型提升
* 结论:当容量小的数据类型的变量与容量大的数据类型的变量做运算时,结果自动提升为容量大的数据类型。
*
* 说明:此时的容量大小指的是,表示数的范围的大和小。比如:float容量要大于long的容量。
*
* byte、char、short ==> int ==> long ==> float ==> double
*
* 特别的:当byte、char、short 三种类型的变量做运算时,结果为int型
*
* 2、强制类型转换
*/
public class VariableTest {
public static void main(String[] args) {
byte b1 = 127;
int i1 = 128;
//byte i2 = b1 + i1; //编译不通过
int i2 = b1 + i1;
long l1 = b1 + i1;
System.out.printf("i2: %s\n", i2);
System.out.printf("l1: %s\n", l1);
float f1 = b1 + i1;
System.out.printf("b1: %s\n", b1);
short s1 = 123;
double d1 = s1 + 10;
System.out.printf("d1: %s\n", d1);
//=============================================
char c1 = 'a'; //97
int i3 = c1 + 10;
System.out.printf("i3: %s\n", i3);
short s2 = 10;
//short s3 = c1 + s2; //编译不通过
byte b2 = 10;
//byte b3 = c1 + b2; //编译不通过
//short s3 = s2 + b2; //编译不通过
//short s4 = b1 + b2; //编译不通过
}
}
(8)强制类型转换
- 自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符:
()
,但可能造成精度降低或溢出,格外要注意。 - 通常,字符串不能直接转换为基本类型,但通过基本类型对应的包装类则可以实现把字符串转换成基本类型。
- 如:
String a = “43”; int i = Integer.parseInt(a);
- boolean类型不可以转换为其它的数据类型。
示例:
/**
* @author: huxingxin
* @date: 2022/11/11 23:07:15
* @description:
* 强制类型转换:自动类型提升运算的逆运算。
* 1、需要使用强转符 ()
* 2、注意点:强制类型转换,可能导致精度损失。
*/
public class VariableTest {
public static void main(String[] args) {
double d1 = 123.4;
int i1 = (int)d1; //截断操作
System.out.printf("i1: %s\n", i1);
long l1 = 123;
short s1 = (short)l1;//没有精度损失
System.out.printf("s1: %s\n", s1);
int i3 = 128;
byte b1 = (byte)i3; // -128 精度损失
System.out.printf("b1: %s\n", b1);
}
}
(9)字符串类型:String
- String不是基本数据类型,属于引用数据类型
- 使用方式与基本数据类型一致。例如:
String str = "abcd";
- 一个字符串可以串接另一个字符串,也可以直接串接其他类型的数据。
示例:
/**
* @author: huxingxin
* @date: 2022/11/11 23:31:49
* @description:
* String类型变量的使用
* 1、String类型属于引用数据类型,翻译为字符串
* 2、声明String类型变量时,使用一对 ""
* 3、String类型可以和8种基本数据类型做运算,且运算只能是连接运算:+
* 4、运算的结果仍是String类型。
*/
public class StringTest {
public static void main(String[] args) {
String s1 = "";
System.out.printf("s1: %s\n", s1);
String s2 = "Hello Word";
System.out.printf("s2: %s\n", s2);
//String s3 = 'a'; 编译不通过
//char c1 = ''; //编译不通过
int number = 1001;
String numberStr = "学号:";
String info = numberStr + number;//连接运算
System.out.printf("info: %s\n", info);
boolean b1 = true;
String info1 = info + b1;
System.out.printf("info1: %s\n", info1);
}
}
两个关于String的练习题
public class StringTest {
public static void main(String[] args) {
//第一题 判断以下的输出结果
char c = 'a'; //a:97 A:65
int number = 10;
String str = "hello";
System.out.println(c + number + str);//107hello
System.out.println(c + str + number);//ahello10
System.out.println(c + (number + str));//a10hello
System.out.println((c + number) + str);//107hello
System.out.println(str + number + c);//hello10a
//第二题:可以打印出 (* *) 的语句
System.out.println("* *"); //可以
System.out.println('*' + '\t' + '*');//93
System.out.println('*' + "\t" + '*');//可以
System.out.println('*' + '\t' + "*");//51*
System.out.println('*' + ('\t' + "*"));//可以
}
}
6、进制
(1)关于进制
- 所有数字在计算机底层都以二进制形式存在。
- 对于整数,有四种表示方式:
- 二进制(binary):0,1 ,满2进1.以
0b
或0B
开头。 - 十进制(decimal):0-9 ,满10进1。
- 八进制(octal):0-7 ,满8进1. 以数字
0
开头表示。 - 十六进制(hex):0-9及A-F,满16进1. 以
0x
或0X
开头表示。此处的A-F不区分大小写。- 如:
0x21AF +1= 0X21B0
- 如:
- 二进制(binary):0,1 ,满2进1.以
(2)二进制
Java整数常量默认是int类型,当用二进制定义整数时,其第32位是符号位;当是long类型时,二进制默认占64位,第64位是符号位
二进制的整数有如下三种形式:
- 原码:直接将一个数值换成二进制数。最高位是符号位
- 负数的反码:是对原码按位取反,只是最高位(符号位)确定为1。
- 负数的补码:其反码加1。
计算机以二进制补码的形式保存所有的整数。
- 正数的原码、反码、补码都相同
- 负数的补码是其反码+1
为什么要使用原码、反码、补码表示形式呢?
- 计算机辨别“符号位”显然会让计算机的基础电路设计变得十分复杂! 于是人们想出了将符号位也参与运算的方法. 我们知道, 根据运算法则减去一个正数等于加上一个负数, 即:
1-1 = 1 + (-1) = 0
, 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了。
(3)二进制==>十进制
(4)进制间转化
进制的基本转换
- 十进制 二进制互转
- 二进制转成十进制 乘以2的幂数
- 十进制转成二进制 除以2取余数
- 二进制 八进制互转
- 二进制 十六进制互转
- 十进制 八进制互转
- 十进制 十六进制互转
思路:用二进制作为中转
二进制==>八进制 :把3位看作一个数,然后将结果拼接
二进制==>十六进制 :把4位看作一个数,然后将结果拼接
八进制==>二进制:每个数拆成3位,然后合在一起
十六进制==>二进制:每个数拆成4位,然后合在一起
练 习
将以下十进制数转换为十六进制和二进制
123
256 87 62
将以下十六进制数转换为十进制和二进制
0x123
0x25F
0x38
0x62
7、运算符
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。
- 算术运算符
- 赋值运算符
- 比较运算符(关系运算符)
- 逻辑运算符
- 位运算符
- 三元运算符
(1)算术运算符
算术运算符的注意问题
- 如果对负数取模,可以把模数负号忽略不记,如:
5 % -2 = 1
。 但被模数是负数则不可忽略。此外,取模运算的结果不一定总是整数。 - 对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。
- “+”除字符串相加功能外,还能把非字符串转换成字符串。
算数运算符的使用
/**
* @author: huxingxin
* @date: 2022/11/14 9:05:17
* @description:
* 运算符之一:算数运算符
* +(加号) - * / %(取模) i++ ++i i-- --i +(连接符)
*/
public class OperatorTest {
public static void main(String[] args) {
//除号:/
int i1 = 12;
int i2 = 5;
int i3 = i1 / i2;
System.out.printf("i3:%s\n", i3);
int i4 = i1 / i2 * i2;
System.out.printf("i4:%s\n", i4);
double d1 = i1 / i2;
System.out.printf("d1:%s\n", d1);
double d2 = i1 / i2 + 0.0;
System.out.printf("d2:%s\n", d2);
double d3 = i1 / (i2 + 0.0);
System.out.printf("d3:%s\n", d3);
double d4 = (double) i1 / i2;
System.out.printf("d4:%s\n", d4);
double d5 = (double)(i1 / i2);
System.out.printf("d5:%s\n", d5);
//取模运算:%
//结果的符号与被模数的符号相同。
//开发中经常使用 % 来判断能否被除尽的情况。
int a1 = 12;
int b1 = 5;
System.out.println("a1 % b1: " + a1 % b1);
int a2 = -12;
int b2 = 5;
System.out.println("a2 % b2: " + a2 % b2);
int a3 = 12;
int b3= -5;
System.out.println("a3 % b3: " + a3 % b3);
int a4 = -12;
int b4 = -5;
System.out.println("a4 % b4: " + a4 % b4);
//单目运算符
// ++i 先自增1,后运算
// i++ 先运算,后自增1
int num = 10;
int result = ++num;
System.out.printf("num: %s\n", num);
System.out.printf("result: %s\n", result);
int num1 = 10;
int result1 = num++;
System.out.printf("num1: %s\n", num1);
System.out.printf("result1: %s\n", result1);
int num2 = 10;
num2++;//++num2
int result3 = num2;
System.out.printf("result3: %s\n", result3);
//注意点
short s = 10;
//s = s + 1;//编译失败
//s = (short)(s + 1);//正确的
s = ++s;//自增1不会改变本身变量的数据类型
System.out.printf("s:%s\n", s);
byte bt1 = 127;
System.out.printf("bt1++: %s\n", ++bt1);
int in1 = 1;
int in2 = 1;
System.out.printf("in1++:%s\n", ++in1);
System.out.printf("in2++:%s\n", in2++);
// --i 先自减1,后运算
// i-- 先运算,后自减1
int e = 10;
int e1 = --e;
System.out.printf("e:%s\n", e);
System.out.printf("e1:%s\n", e1);
}
}
算数运算符的练习
/**
* @author: huxingxin
* @date: 2022/11/14 10:39:09
* @description:
*/
public class OperatorTest1 {
public static void main(String[] args) {
int i1 = 10;
int i2 = 20;
int i = i1++;
System.out.println("i = " + i);//10
System.out.println("i1 = " + i1);//11
i = ++i1;
System.out.println("i = " + i);//12
System.out.println("i1 = " + i1);//12
i = i2--;
System.out.println("i = " + i);//20
System.out.println("i2 = " + i2);//19
i = --i2;
System.out.println("i = " + i);//18
System.out.println("i2 = " + i2);//18
}
}
/**
* @author: huxingxin
* @date: 2022/11/14 10:39:09
* @description:
*练习:随机给出一个整数,打印显示他的个位数、十位数、和百位数的值。
*格式如下:
* 数字xxx的情况如下:
* 个位数:
* 十位数:
* 百位数:
*
* 例如
* 数字153的情况如下:
* 个位数:3
* 十位数:5
* 百位数:1
*
*/
public class OperatorTest2 {
public static void main(String[] args) {
int number = 123456;
int ge = number % 10;
int shi = number % 100 / 10;
int bai = number % 1000 / 100;
System.out.println("数字" + number + "的情况如下:");
System.out.println("个位数:" + ge);
System.out.println("十位数:" + shi);
System.out.println("百位数:" + bai);
}
}
(2)赋值运算符
赋值运算符的使用
/**
* @author: huxingxin
* @date: 2022/11/14 9:05:17
* @description:
* 运算符之二:赋值运算符
* = += -= *= /= %=
*/
public class OperatorTest {
public static void main(String[] args) {
//赋值符号 =
int i1 = 10;
int i2 = 20;
int j1, j2;
//连续赋值
j1 = j2 = 100;
int k1 = 10, k2 = 20;
//+= -= *= /= %=
int number = 10;
number += 2;
System.out.println("number: " + number);
number %= 10;
System.out.println("number: " + number);
byte b = 10;
//b = b + 1; 编译不通过
b += 1;//不会改变变量本身的数据类型
System.out.println("b: " + b);
//开发中,如果希望变量实现+2的操作,有几种方法?(前提 int num = 10)
//方式一 num = num + 2;
//方式二 num += 2; (推荐)
//开发中和,如果希望变量实现+1的操作马,有几种方法?(前提 int num = 10;)
//方式一 num = num + 1;
//方式二 num += 1;
//方式三 ++ num; 或者 num ++; (推荐)
}
赋值运算符的练习
/**
* @author: huxingxin
* @date: 2022/11/14 14:27:38
* @description:
*/
public class _2赋值运算符的练习 {
public static void main(String[] args) {
//练习1: 1和2有什么区别
short s = 3;
//s = s + 3; //1
//s += 2; //2
//练习二:
int i = 1;
i *= 0.1;
System.out.println("i: " + i);//0
i ++;
System.out.println("i: " + i);//1
//练习三
int m = 2;
int n = 3;
n *= m++;
System.out.println("m = " + m);//3
System.out.println("n = " + n);//6
//练习四
int j = 10;
j += (j++) + (++j);
//j = j + (j++) + (++j);//赋值运算符最后进行运算
System.out.println("j = " + j);//32
}
}
(3)比较运算符
比较运算符的结果都是boolean型,也就是要么是true,要么是false。
比较运算符“==”不能误写成“=”
比较运算符的使用
/**
* @author: huxingxin
* @date: 2022/11/14 15:27:59
* @description:
* 算数运算符之三:比较运算符
* == != > < >= <= instanceof
* 结论:
* 1、比较运算符的结果是boolean类型
* 2、区分 == 和 =
*/
public class OperatorTest {
public static void main(String[] args) {
int i = 10;
int j = 20;
System.out.println("i == j : " + (i == j));//false
System.out.println("i = j : " + (i = j));//20
boolean b1 = true;
boolean b2 = false;
System.out.println("b1 == b2 : " + (b1 == b2));//false
System.out.println("b2 = b1 : " + (b2 = b1));//true
}
}
比较运算符的练习
/**
* @author: huxingxin
* @date: 2022/11/14 15:35:50
* @description:
*/
public class OperatorTest {
public static void main(String[] args) {
boolean b1 = false;
if (b1 == true){
System.out.println("结果为真");
} else{
System.out.println("结果为假");
}
if (b1 = true){
System.out.println("结果为真");
} else{
System.out.println("结果为假");
}
}
}
(4)逻辑运算符
&:逻辑与
| :逻辑或
!:逻辑非
&& :短路与
|| :短路或
^ :逻辑异或
- 逻辑运算符用于连接布尔型表达式,在Java中不可以写成
3<x<6
,应该写成x>3 & x<6
。 - “&”和“&&”的区别:
- 单&时,左边无论真假,右边都进行运算;
- 双&时,如果左边为真,右边参与运算,如果左边为假,那么右边不参与运算。
- “|”和“||”的区别同理,||表示:当左边为真,右边不参与运算。
- 异或( ^ )与或( | )的不同之处是:当左右都为true时,结果为false。
- 理解:异或,追求的是“异”!
逻辑运算符的使用
/**
* @author: huxingxin
* @date: 2022/11/14 15:39:12
* @description:
* 算数运算符之四:逻辑运算符
* & && | || ! ^(异或)
*
* 说明:逻辑运算符操作的都是boolean类型的变量
*/
public class OperatorTest {
public static void main(String[] args) {
//区分:& 与 &&
//相同点1:& 与 && 的运算结果都是相同的。
//相同点2:当符号左边是true时,二者都会执行符号右边的运算。
//不同点:当符号左边是false时,&会继续执行符号右边的运算,&&不再执行符号右边的运算。
//开发中推荐使用 &&
boolean b1 = false;
int number1 = 10;
if (b1 & (number1++ > 0)){
System.out.println("Hello Word");
}else {
System.out.println("Hello Java");
}
System.out.println("number1: " + number1);//11
boolean b2 = false;
int number2 = 10;
if (b2 && (number2++ > 0)){
System.out.println("Hello Word");
}else {
System.out.println("Hello Java");
}
System.out.println("number2: " + number2);//10
// 区分:| 与 ||
//相同点1:| 与 || 的运算结果都是相同的。
//相同点2:当符号左边是false时,二者都会执行符号右边的运算。
//不同点:当符号左边是true时,|会继续执行符号右边的运算,||不再执行符号右边的运算。
//开发者推荐使用 ||
boolean b3 = true;
int number3 = 10;
if (b3 | (number3++ >0)){
System.out.println("Hello Word");
}else {
System.out.println("Hello Java");
}
System.out.println("number3: " + number3);//11
boolean b4 = true;
int number4 = 10;
if (b4 || (number4++ >0)){
System.out.println("Hello Word");
}else {
System.out.println("Hello Java");
}
System.out.println("number4: " + number4);//10
}
}
逻辑运算符的练习
/**
* @author: huxingxin
* @date: 2022/11/14 16:55:34
* @description:
*/
public class OperatorTest {
public static void main(String[] args) {
//第一题
int x = 1;
int y =1;
if (x++ == 2 & ++y == 2){
x = 7;
}
System.out.println("x = " + x + ", y = " + y);// x = 2, y = 2
//第二题
int x1 = 1, y1 =1;
if (x1++ == 2 && ++y1 == 2){
x1 = 7;
}
System.out.println("x = " + x1 + ", y = " + y1);// x1 = 2, y1 = 1
//第三题
int x2 = 1, y2 =1;
if (x2++ == 1 | ++y2 == 1){
x2 = 7;
}
System.out.println("x = " + x2 + ", y = " + y2);//x2 = 7, y2 = 2
//第四题
int x3 = 1, y3 =1;
if (x3++ == 1 || ++y3 == 1){
x3 = 7;
}
System.out.println("x = " + x3 + ", y = " + y3);//x3 = 7, y3 = 1
//第五题
boolean x4 = true;
boolean y4 = false;
short z = 42;
if(y4 == true)
if ((z++ == 42) && (y4 = true)) z++;// z = 44
if ((x4 = false) || (++z == 45)) z++; // z = 46
System.out.println("z = " + z);
}
}
(5)位运算符
图解
位运算符的使用
/**
* @author: huxingxin
* @date: 2022/11/14 19:11:48
* @description:
* 结论:
* 1、位运算符操作的都是整形的数据。
* 2、 <<:在一定范围内,每向左移动一位,相当于 *2
* >>:在一定范围内,每向右移动一位,相当于 /2
*/
public class OperatorTest {
public static void main(String[] args) {
int i = 21;
System.out.println("i << 1 : " + (i << 1));//42
System.out.println("i << 1 : " + (i << 2));//84
System.out.println("i << 27 : " + (i << 27));//-1476395008
int j = -21;
System.out.println("j << 1 : " + (j << 1));//-42
System.out.println("j << 2 : " + (j << 2));//-84
//面试题:最高效方式的计算 2 * 8?
// 2 << 3 或者 8 << 2
}
}
位运算符的练习
/**
* @author: huxingxin
* @date: 2022/11/14 22:53:03
* @description:
*/
public class OperatorTest {
public static void main(String[] args) {
//练习一、交换两个变量的值
int a = 10;
int b = 20;
//方式一: 都是2的倍数
// a = a << 1;
// b = b >> 1;
// System.out.println("a: " + a);
// System.out.println("b: " + b);
//方式2:定义临时变量
// int temp = a;
// a = b;
// b = temp;
// System.out.println("a: " + a);
// System.out.println("b: " + b);
//方式三:相加减
//好处: 不用定义临时变量
//弊端:(1)相加操作可能超出存储范围。 (2)有局限性,只能用于数值类型。
// a = a + b;
// b = a - b;
// a = a - b;
// System.out.println("a: " + a);
// System.out.println("b: " + b);
//方式4:异或 m = m ^ n ^ n
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println("a: " + a);
System.out.println("b: " + b);
}
}
(6)三元运算符
格式:
(条件表达式)?表达式1:表达式2;
- 为true,运算后的结果是表达式1;
- 为false,运算后的结果是表达式2;
表达式1和表达式2为同种类型
三元运算符与if-else的联系与区别:
- 1)三元运算符可简化if-else语句
- 2)三元运算符要求必须返回一个结果。
- 3)if后的代码块可有多个语句
三元运算符的使用
/**
* @author: huxingxin
* @date: 2022/11/14 23:26:20
* @description:
* 运算符之六:三元运算符
* 1、结构:(条件表达式) ? 表达式一 : 表达式二。
* 2、说明:
* (1)条件表达式的结果为boolean类型。
* (2)根据条件表达式真或假,决定执行表达式1,还是表达式2。
* 如果表达式结果为true,则执行表达式1。
* 如果表达式结果为false,则执行表达式2。
* (3)表达式1和表达式2要求是一致的。
* (4)三元运算符可以嵌套使用。
*
* 3、凡是可以使用三元运算符的地方,都可以改写为if-else。
* 反之,不成立。
*
* 4、如果程序既可以使用三元运算符,又可以使用if-else结构,那么优先选择三元运算符。原因:简洁、执行效率高。
*
*/
public class OperatorTest {
public static void main(String[] args) {
//获取两个整数的较大值
int a = 1;
int b = 2;
int max = (a > b) ? a : b;
System.out.println("a: " + a);
System.out.println("b: " + b);
System.out.println("较大值为: " + max);
// (a > b) ? 1 : "hello"; 编译不通过
String maxStr = (a > b) ? "a大" : ((a == b) ? "a和b相等" : "b大");
System.out.println(maxStr);
//获取三个数的较大值
int i = 1;
int j = 2;
int k = 3;
int temp = (i > j) ? i : j;
temp = (temp > k) ? temp : k;
System.out.println("最大的数为:" + temp);
}
}
8、运算符的优先级
运算符有不同的优先级,所谓优先级就是表达式运算中的运算顺序。如右表,上一行运算符总优先于下一行。
只有单目运算符、三元运算符、赋值运算符是从右向左运算的。