第二章 基础语法
本章内容:
第一部分:
Java语法中一些特殊英文单词的含义和基本功能,以及自定义名称的标准规范
- 关键字和保留字
- 标识符
第二部分:
Java的数据定义和表示方式
- 变量
- 数据类型
- 数据类型的转换
第三部分:
Java语言中使用运算符进行各种运算处理的方法
- 运算符和标点符号
一、关键字(keyword)
-
说明:
高级编程语言由一系列单词和符号组成,并且能与计算机进行交互,实现逻辑功能。为了让程序员与计算机能够进行更好的交互,会提前给一些单词赋予特殊的含义,这些在程序语言中具有特殊含义的单词叫作关键字。其中有一部分关键字在Java中并没有使用,暂时没有赋予特殊含义,这部分称为保留字。
-
注意:
- 关键字比较多,不需要死记硬背,学到哪里记到哪里即可。
- 官方地址: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
1、 关键字
(1)定义:
被Java语言赋予了特殊含义,用做专门用途的字符串(或单词)
(2)特点:
关键字都是小写字母。
2、 保留字
goto
goto语句在其他语言中叫作“无限跳转”语句。Java语言不再使用goto语句,这是因为goto语句会破坏程序结构。在Java语言中可以通过break、continue和return实现“有限跳转”。
const
const在其他语言中是声明常量的关键字,在Java语言中使用final
方式声明常量。
3、 特殊值
true、false、null
这三个特殊值看起来像是关键字,但实际上是字面量值,表示特殊的布尔值和空值。后面在给标识符命名时,同样要避开使用特殊值。
二、标识符( identifier)
-
定义:
Java中变量、方法、类等要素命名时使用的字符序列,称为标识符。
-
标识符的命名规则(必须遵守的
硬性规定
):
- 由26个英文字母大小写,0-9 ,_或 $ 组成
- 虽然官方说只要是Unicode字符集中的字符都可以,但是不推荐使用上述以外的,如中文等
数字不可以开头。
不能包含空格。
不可以使用关键字和保留字,但能包含关键字和保留字。
Java中严格区分大小写,长度无限制。
-
标识符的命名规范(建议遵守的
软性要求
): -
tips:
- 凡是自己可以起名字的地方都叫标识符。
- 下划线问题:JDK9版本开始,禁止独立的 _ 作为标识符
- 在起名字时,为了提高阅读性,要尽量有意义,见名知意。
- 可参考《阿里巴巴Java开发手册-1.7.1-黄山版》
三、字面常量值
1、什么是字面常量值?
它们是在程序中固定写死的值。
2、规则
- 所有字符串类型的字面常量值必须加
""
- 所有char类型的字面常量值必须加
''
- boolean类型的常量值只有两个:
true
、false
- 浮点型的常量值,没有加F或f都是double类型,如果要表示float类型,必须加F或f
- 如果是直接写整数常量值,不加L或小写l,默认按照int处理,如果要表示为long类型,需要加L或小写l(推荐用大写L)
3、各种数据类型的表示
class LiteralValueDemo{
public static void main(String[] args){
System.out.println("hello");//String类型的字面常量值
System.out.println(18);//int类型的字面常量值
System.out.println(18.0);//double类型的字面常量值
System.out.println(true);//boolean类型的字面常量值
System.out.println('男');//char类型的字面常量值
}
}
4、举例——使用不同类型的常量值表示个人信息
class MyInfoTypeDemo{
public static void main(String[] args){
System.out.println("姓名");//姓名 String
System.out.println(18);//年龄 int
System.out.println('女');//性别 char
System.out.println(84.5);//体重 double
System.out.println(true);//是否已婚 boolean
System.out.println(57814714855L);//存款特别多 long
System.out.println("33088119961202157X");//身份证号 String
}
}
五、变量
1、概述
- 变量实质:
内存中的一块数据存储区域,该区域有自己的名称(变量名)和类型(数据类型)
-
变量三要素:数据类型、变量名、变量值
-
数据类型
决定了这个变量中要存储的数据值的类型
及这块内存的宽度
-
变量名
就是一个标识符,方便在程序中使用 -
变量值
就是这个变量具体存储的值
-
2、 变量的使用
所谓使用,是指在变量的作用域内将变量中的值拿出来进行打印、运算、比较
等。
-
声明
数据类型 变量名;
变量的声明相当于向JVM申请一部分指定数据类型大小的内存。
不同的数据类型,需要占用的内存大小是不同的。另外,JVM中每字节的内存都有自己的编号,称为
内存地址
,但是在程序中直接使用内存地址是极其不方便的,因此需要给这部分内存命名,方便在程序中对这部分内存进行访问和使用。
-
赋值
变量名 = 值;
变量的赋值相当于将符号“=”右边的值放到对应的内存中。
- 变量的初始化
第一次给变量赋值称为变量的初始化,即同时声明和赋值
数据类型 变量名 = 值;
3、 变量的使用要求
- 变量必须先声明再使用
- 变量必须在初始化后才能使用
- 变量有作用域(即一个
{}
内),并且在同一个作用域中不可以重复命名,但是可以重复赋值 - 变量的值可以变化,但必须在变量声明的数据类型范围内
六、最终变量/常量
1、什么是最终变量/常量?
它的值不可以修改。这种常量或最终变量也有一个标识符名称,但是它代表的值在整个程序运行期间是不可以修改的。
2、声明最终变量/常量
final 数据类型 常量名 = 值;
【注意】:此时的常量名建议使用全大写字母写法。
3、直接使用常量值和声明标识符常量的区别
-
直接使用常量值,对于后期维护来说成本较高,一旦需求变化,需要修改很多地方
-
声明标识符常量,对于后期维护来说比较简单,修改标识的代码的值即可
-
声明标识符常量,更便于代码阅读,更见名知意
class FinalDemo{
public static void main(String[] args){
//先声明两个double类型的变量,分别表示两个圆的半径
double radius1 = 2.5;
//double radius1 = Math.random();
double radius2 = 1.2;
//再声明一个变量,用来表示圆周率
//加一个要求,圆周率PI的值在程序运行期间不允许改变,即不能被重新赋值
//除了依靠程序员的自觉之外,希望从技术或语法的角度限定它不能修改
final double PI = 3.14;
System.out.println("PI = " + PI);
//再声明两个double类型的变量,表示两个圆的面积
double area1 = PI * radius1 * radius1;
double area2 = PI * radius2 * radius2;
//再声明两个double类型的变量,表示两个圆的周长
double perimeter1= 2 * PI * radius1;
double perimeter2= 2 * PI * radius2;
//输出显示
System.out.println("圆1的半径:" + radius1 +",面积:" + area1 +",周长:" + perimeter1);
System.out.println("圆2的半径:" + radius2 +",面积:" + area2 +",周长:" + perimeter2);
}
}
七、数据类型
Java是一门强类型语言,根据存储元素的需求不同,我们将数据类型划分为基本数据类型和引用数据类型。本章节主要学习基本数据类型。
基本数据类型 | 关键字 | 内存占用 | 取值范围 |
---|---|---|---|
字节型 | byte | 1个字节 | -128 至 127 |
短整型 | short | 2个字节 | -32768 至 32767 |
整型 | int(默认) | 4个字节 | -231 至 231-1 ( -2147483648—2147483647) |
长整型 | long | 8个字节 | -263 至 263-1 (19位数字) |
单精度浮点数 | float | 4个字节 | 1.4013E-45 至 3.4028E+38 |
双精度浮点数 | double(默认) | 8个字节 | 4.9E-324 至 1.7977E+308 |
字符型 | char | 2个字节 | 0 至 65535 |
布尔类型 | boolean | 1个字节 | true,false(可以做判断条件使用) |
1、 计算机存储单位(补充知识)
-
**位(bit):**是数据存储的
最小
单位。二进制数系统中,每个0或1就是一个位,叫做bit(比特),其中8 bit 就称为一个字节(Byte)。 -
**字节(Byte):**是计算机用于
计量存储容量
的基本
单位,一个字节等于8 bit。 -
转换关系:
-
8 bit = 1 Byte
-
1024 Byte = 1 KB
-
1024 KB = 1 MB
-
1024 MB = 1 GB
-
1024 GB = 1 TB
-
-
计算机底层如何存储数据见本章 3.10【拓展】进制
2、 整形
字节型byte、短整型short、整形int、长整型long
【注意】
- Java的整数类型常量值默认为 int 型。
- Java程序中变量通常声明为int型,除非不足以表示较大的数,才使用long。
- 定义long类型的变量,赋值时需要以"
l
"或"L
"作为后缀。 - Java各整数类型有固定的表数范围和字段长度,不受具体操作系统的影响,以保证Java程序的可移植性。
3、 浮点型
单精度float、双精度double
【注意】
- Java 的浮点型常量默认为double型。
- 定义float类型的变量,赋值时需要以"
f
"或"F
"作为后缀。 - float:
单精度
,尾数可以精确到7位有效数字。很多情况下,精度很难满足需求。 - double:
双精度
,精度是float的两倍,开发中通常用double类型来表示小数。 - 浮点型常量值有两种表示形式:
- 十进制数形式。如:5.12 512.0f .512 (必须有小数点)
- 科学计数法形式。如:5.12e2 512E2 100E-2
- e代表指数,如5.12e2=5.12*10^2
- 与整数类型类似,Java 浮点类型也有固定的表数范围和字段长度,不受具体操作系统的影响。
4、 字符型
字符型char
字符型用于保存单个字符,字符型常量要求使用单引号(如'a'
)引起来。字符型底层依然是以整型(相当于无符号整型)存储的,因此需要借助一个字符编码集,将每个字符一一对应成一个整型。Java使用的是Unicode字符集。Unicode字符集支持全世界所有书面语言的字符,它是固定长度编码方式,兼容ASCII字符集。
- 字符型变量的三种表现形式:
**形式1:**使用单引号
' '
括起来的单个字符
。例如:
char c1 = ‘a’;
char c2 = ‘中’;
char c3 = ‘9’;
**形式2:**直接使用
Unicode值
来表示字符型常量:‘\uXXXX
’。其中,XXXX代表一个十六进制整数。'\u0000’显示到控制台上是一个空格
例如:\u0023 表示 ‘#’。
**形式3:**Java中还允许使用
转义字符‘\’
来将其后的字符转变为特殊字符型常量。例如:
char c3 = ‘\n’;
// '\n’表示换行符
- 编码与字符转换关系
char 型数据用来表示通常意义上“
字符
”(占2字节)Java中的所有字符都使用Unicode编码,故一个字符可以存储一个字母,一个汉字,或其他书面语的一个字符。
char类型是可以进行运算的。因为它都对应有Unicode码,可以看做是一个数值。
转义字符 | 说明 | Unicode表示方式 |
---|---|---|
\n | 换行符 | \u000a |
\t | 制表符 | \u0009 |
\" | 双引号 | \u0022 |
\' | 单引号 | \u0027 |
\\ | 反斜线 | \u005c |
\b | 退格符 | \u0008 |
\r | 回车符 | \u000d |
5、 布尔类型
布尔类型boolean
-
boolean类型数据只有两个值:
true
、false
,无null
或者其他。 -
boolean 类型用来判断逻辑条件,一般用于流程控制语句中:
-
if条件控制语句;
-
while循环控制语句;
-
for循环控制语句;
-
do-while循环控制语句;
-
三元运算符的条件
-
-
-
不可以使用0或非0的整数替代false和true,这点和C语言不同。
-
Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达所操作的boolean值,在编译之后都使用java虚拟机中的int数据类型来代替:true用1表示,false用0表示。——《java虚拟机规范第8版》
八、数据类型的转换
Java语言只支持布尔型之外的七大基本数据类型间的转换,它们之间的转换类型分为自动类型转换和强制类型转换。
1、 自动类型转换
当我们将一个基本数据类型的值直接赋给另一个不同类型的基本数据类型的变量时,如果赋值成功,则说明此时系统进行了一次自动类型转换,Java语言规范将其称为Wideding Conversion。如果赋值失败,则说明系统不能进行自动类型转换。
- 转换规则
自动类型转换需要满足目标类型的表示范围 大于 源类型的示数范围的要求,这就相当于将一个体积为2立方厘米的立方体放在体积为5立方厘米的立方体盒子中。
- 转换关系
基本数据类型的自动转换关系如图所示,根据箭头指向自动转换,反之,则不可以。
实线箭头表示无信息丢失的转换
虚线箭头表示可能有精度损失的转换
-
注意事项
-
当多种类型的数据进行混合运算时,系统首先自动将所有数据转换成容量最大的数据类型,再进行计算。
int i = 1; byte b = 1; double d = 1.0; double sum = i + b + d; //只能用double接收,混合运算,升级为double
-
byte、short、char之间在计算时首先会转换为int类型再运算。(因为Java中整形常量的默认数据类型为int)
byte b1 = 1; byte b2 = 2; byte b3 = b1 + b2; //编译报错,b1 + b2自动升级为int char c1 = '0'; char c2 = 'A'; int i = c1 + c2; //至少需要使用int类型来接收 System.out.println(c1 + c2); //113
-
2、 强制类型转换
在一些开发场景中,我们也需要面对将自动转换关系图所示箭头右边类型转换为左边类型的情况,这时候就要进行强制转换,否则编译会报错,代码如下所示:
int a = 200;
byte b = a; //编译报错
Java语言规范将强制类型转换称为Narrow Conversion。试想,如果将一个体积为5立方厘米的立方体放在体积为2立方厘米的立方体盒子中,正常来讲放不进去。如果要放进去,则要削去一部分体积,从而造成数据丢失。
-
语法格式
目标数据类型 变量名 = (目标数据类型)被强转变量值; //()中的目标数据类型必须<=变量值的数据类型
-
转换规则
-
将32位int类型强转为8位byte类型,则需要截断前面的24位,只保留右边8位。
-
同理,将32位int类型强转为16位short类型,需要截断前面16位,保留后面16位。
32位的int类型:65540 补码:0000 0000 0000 0001 0000 0000 0000 0100 截断16位后: 补码:0000 0000 0000 0100 反码:0000 0000 0000 0100 原码:0000 0000 0000 0100 最终转化位16位short类型:4
-
目标类型是整型,源类型是浮点型,将直接截断浮点型的小数部位,这会造成精度损失。例如,int iValue=(int )12.5;,将其强转后最终得到的iValue的值是12。
-
3、 基本数据类型与String的运算
-
字符串类型:String
-
String属于
引用数据类型
,不是基本数据类型。 -
使用一对
""
来表示一个字符串,内部可以包含0个、1个或多个字符。 -
声明方式与基本数据类型类似。例如:String str = “尚硅谷”;
-
-
运算规则
- 任意八种基本数据类型的数据与String类型只能进行连接“+”运算,且结果一定也是String类型
- String类型
不能
通过强制类型()转换转为其他的类型*
4、 小结
数据类型转换的相关内容可以总结为如下几点。
-
表达式类型自动提升的一般原则:
表达式结果的类型为操作数中最大的类型。
-
byte类型和short类型进行运算时,系统自动当作int类型处理。
-
char变量可以直接保存为int常量值,但不能直接保存为int变量值,char类型进行运算时,系统自动当作int类型处理。
-
自动类型转换的逆过程是将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符号,但可能造成精度降低或溢出,需要格外注意。
-
强制转换符号为小括号,优先级非常高,故强制转换表达式结果的类型时,需要将表达式用小括号包起来,提升优先级。
-
布尔类型不可以转换为其他的数据类型。
九、运算符(Operator)
-
定义
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。Java语言中运算符共38个。
-
分类
按
功能
分为:
分类 | 运算符 |
---|---|
算术运算符(7个) | + - * / % ++ -- |
赋值运算符(12个) | = += -= *= /= %= >>= <<= >>>= &= ` |
比较(或关系)运算符(6个) | > >= < <= == != |
逻辑运算符(6个) | & ` |
位运算符(7个) | & ` |
条件运算符(1个) | (条件表达式)? 结果1: 结果2 |
Lambda运算符(1个) | -> (后面讲解) |
按照操作数个数
分为:
分类 | 运算符 |
---|---|
一元运算符(单目运算符) | 正号(+)、负号(-)、++、–、!、~ |
二元运算符(双目运算符) | 除了一元和三元运算符剩下的都是二元运算符 |
三元运算符 (三目运算符) | (条件表达式)?结果1:结果2 |
1、 算术运算符
算术运算符用于进行算术运算,基本数据类型运算表达式结果的类型为数值型。
(1) 除法运算符/
- 运算时,被除数、除数若都是整型,则结果就为整型,且结果以截断方式取整;
- 若被除数或除数是浮点型,则结果就是浮点型。
示例:
System.out.println(10/3); //结果:3
System.out.println(10.5/3); //结果:3.5
除数为0或0.0的异常情况:
- 除数是0,被除数是整形,会报
ArithmeticException
异常 - 除数是0,被除数是浮点型,不会报异常,得到的结果是
Infinity
- 除数是0.0,不会报异常,得到的结果是
Infinity
(2)取模运算符%
-
取模运算类似于数学中的求余数。在实际开发中,经常使用%来判断能否被除尽的情况。
-
取模运算不仅限于整型,这一点和数学中的求余不同。
-
取模运算结果的符号与被模数的符号相同。
System.out.println(10%3); //结果:1 System.out.println(-10.5%3); //结果:-1.5 System.out.println(8.53%1.7); //结果:0.029999999999999583
模数是0的异常情况
- 如果两个操作数都是整型,则结果会报
ArithmeticException
异常 - 如果被除数或除数是浮点型,则结果不会报异常,得到的结果是
NaN
(3)自增运算符++
自增运算可以实现变量值自加1运算。
-
当自增运算作为独立语句使用时,自增运算符
++
在前或在后没区别。 -
当自增运算作为表达式一部分使用时,自增运算符
++
在前或在后是有区别的。操作数在左边:先自增1,再取变量的值做其他运算,即参与运算的是自增之后的值。
操作数在右边:先取变量的值放到操作数栈中,随后自增变量增1,然后计算是用自增之前取的值进行运算。
//示例:
//格式1:前置自增
int i = 10;
int j = ++i;
System.out.println("i = " + i); //i = 11
System.out.println("j = " + j); //j = 11
//格式2:后置自增
int i = 10;
int j = i++;
System.out.println("i = " + i); //i = 11
System.out.println("j = " + j); //j = 10
//格式3:混合运算
int i = 10;
int j = i++ + ++i * i++; //j = 10 + 12*12
System.out.println("i = " + i); //i = 13
System.out.println("j = " + j); //j = 154
- 自减运算符
--
与自增运算符++
同理
(4)字符串连接 +
String
字符串可以和八种基本数据类型变量做运算,且运算只能是连接运算+
,运算的结果仍然是String
类型。
2、 赋值运算符
-
定义:赋值运算符的功能是为变量赋值。最基本的赋值运算符号是
=
。 -
运算顺序:赋值运算符的运算顺序是从右往左,即把等号右边的值赋给等号左边的变量。
-
赋值运算符是二元运算符。
-
注意事项:
-
赋值运算符包括基本赋值运算符
=
和复合赋值运算符+= -= *=
/=
%=
>>=
<<=
>>>= &=
|=
^=
共12个 -
复合赋值运算符由基本赋值运算符
=
与算术运算符+
-
*
/
%
++
--
或 位运算符&
|
^
<<
>>
>>>
组合而成 -
为什么没有~=复合赋值运算符?
因为按位取反
~
是一个一元运算符,可以单独使用来对变量进行取反操作,而不需要与赋值操作结合。 -
=
右边的形式可以是常量值、变量、表达式。 -
=
左边只能是变量。 -
使用复合赋值运算符时,不改变变量类型。当结果超过左边变量的类型时,会自动进行强制类型转换,将右边表达式的结果转换为左边变量的类型,然后再赋给左边变量,所以要考虑精度损失或溢出。
-
赋值操作一定是最后进行运算的。
-
示例:
type a = 127;
//a = a + 1; 编译错误,报错
//a += 1; 将128强转为byte,溢出,a = -128
//a++; 将128强转为byte,溢出,a = -128
3、 比较运算符
-
定义:
比较运算符用以进行关系比较,比较运算符的 逻辑运算符类型为布尔型,往往用于if结构、循环结构条件中,如表所示。
-
运算顺序:比较运算符的运算顺序是从左往右的。
-
比较运算符属于二元运算符。
- 注意事项
==
与!=
既可以用于判断两个基本数据类型变量又可以用于判断两个引用类型变量。- 如果两个操作数为基本数据类型,则
==
与!=
判断的是值是否相等。 - 如果两个操作数为引用类型,则
==
与!=
判断的是两个引用是否指向同一个对象实体或数组实体(后续章节会讲解到引用类型)。
- 如果两个操作数为基本数据类型,则
==
与!=
在判断时,要求两个操作数的类型一致或兼容(所谓兼容类型,是指可以通过自动类型提升实现的类型),否则编译报错!>
<
>=
<=
:只适用于基本数据类型(除boolean类型之外)
4、 逻辑运算符
-
定义:
Java中的逻辑运算符用于表示两个或更多个条件之间的关系。(如:Java中不可以写成3<x<6,应该写成x>3 && x<6)逻辑运算符的操作数都是布尔型的值或表达式,往往用于if结构、循环结构条件中。
-
运算顺序:
逻辑运算符的运算顺序是从左往右的。
-
逻辑运算符除逻辑非
!
,其余都是二元运算符。
运算符 | 名称 | 格式 | 说明 |
---|---|---|---|
& | 逻辑与 | a & b | 当a与b都为true时,结果才为true,反之为false。不管a是否为false,都会判断b |
&& | 短路与 | a && b | 当a与b都为true时,结果才为true,反之为false。如果a为false,则不会判断b |
| | 逻辑或 | a | b | 当a和b中有一个为true时,结果为true,反之为false。不管a是否为true,都会判断b |
|| | 短路或 | a || b | 当a和b中有一个为true时,结果为true,反之为false。如果a为true,则不会判断b |
^ | 逻辑异或 | a ^ b | 当a和b相同时,结果为false;当a和b不同时,结果为true |
! | 逻辑非 | !a | 如果a为true,结果为false,反之为true |
-
&
和&&
、||
和|
的区别有以下几点-
&&
:短路与,如果左边为false,则右边不参与运算,效率较高 -
&
:逻辑与,不管左边是否为false,右边都要参与运算,效率较低 -
||
:短路或,如果左边为true,则右边不参与运算,效率较高 -
|
:逻辑或,不管左边是否为true,右边都要参与运算,效率较低。
-
-
开发中,建议用&&、||
5、 位运算符
-
定义:
位运算符是指按照二进制的规则进行相关运算的运算符,共有七个,除了按位取反
~
,其余的都是二元运算符。 -
说明:
所有的运算都是基于操作数的二进制补码形式进行运算的,计算结果要变回原码。
- 注意:
- 位运算符中没有无符号左移运算符“<<<”。
- 当符号
&
|
^
左右两边为布尔类型时,为逻辑运算符;当符号&
|
^
左右两边为数值类型时,为位运算符。
(1)<< :左移
-
运算规则:
在一定范围内,数据每向左移动n位,相当于原数据 2^n* (正数、负数都适用)
当左移的位数n超过该数据类型的总位数时,相当于左移(n-总位数)位
-
运算过程:3 << 2
(2)>> :右移
-
运算规则:
在一定范围内,数据每向左移动n位,相当于原数据 / 2^n (正数、负数都适用)
如果不能整除,向下取整
-
运算过程:-3 >> 2
(3)>>> :无符号右移
-
运算规则:
在一定范围内,数据每向左移动n位,相当于原数据 / 2^n (正数、负数都适用),往右移动后,左边空出来的位直接补0,结果一定是正数
如果不能整除,向下取整
-
运算过程:-3 >>> 2
(4)& :按位与
按二进制位进行与运算
-
运算规则:
对应位都是1才为1,否则为0。
-
运算过程:6 & 3
(5)| :按位或
按二进制位进行或运算
-
运算规则:
对应位只要有1即为1,否则为0
-
运算过程:6 | 3
(6)^ :按位异或
按二进制位进行异或运算
-
运算规则:
对应位一个为1一个为0,才为1,否则为0。
-
运算过程:6 ^ 3
-
需求实现:
-
高效计算2*8的值。(经典面试题)
2 << 3 或者 8 << 1
-
声明两个变量,用来存储两个整数,如1和2,交换两个变量的值。
//方式一:定义中间变量(推荐,适用于不同数据类型)
int m,n;
int temp = m;
m = n;
n = temp;//方式二:按位异或(只能用于数值类型)
int m,n;
m = m ^ n;
n = m ^ n;
m = m ^ n;//方式三:加减(只能用于数值类型,且可能超出数据类型范围)
//m = m + n; //15 = 10 + 5
//n = m - n; //10 = 15 - 5
//m = m - n; //5 = 15 - 10
-
(7)~ :按位取反
按二进制位进行取反运算
-
运算规则:
对应位为1,则结果为0;对应位为0,则结果为1。
-
运算过程:~ 6
6、 条件运算符
-
定义:实现简单的条件判断。
-
运算顺序:条件运算符的运算顺序是从左往右的。
-
条件运算符是唯一的三元运算符
-
格式:
(条件表达式)? 表达式1:表达式2
-
说明:
-
条件表达式是boolean类型的结果,根据boolean的值选择表达式1或表达式2
-
如果运算后的结果赋给新的变量,要求表达式1和表达式2为同种或兼容的类型
-
十、运算符优先级
-
说明:
-
运算符有不同的优先级,所谓优先级就是在表达式中的运算顺序。
-
上一行中的运算符总是优先于下一行的。
-
-
优先级:
优先级 | 运算符说明 | Java运算符 |
---|---|---|
1 | 括号 | () 、[] 、{} |
2 | 正负号 | + 、- |
3 | 单元(目)运算符 | ++ 、-- 、~ 、! |
4 | 乘法、除法、求余 | * 、/ 、% |
5 | 加法、减法 | + 、- |
6 | 移位运算符 | << 、>> 、>>> |
7 | 关系运算符 | < 、<= 、>= 、> 、instanceof |
8 | 等价运算符 | == 、!= |
9 | 按位与 | & |
10 | 按位异或 | ^ |
11 | 按位或 | ` |
12 | 条件与 | && |
13 | 条件或 | ` |
14 | 三元(目)运算符 | ? : |
15 | 赋值运算符 | = 、+= 、-= 、*= 、/= 、%= |
16 | 位赋值运算符 | &= 、` |
-
开发建议:
-
不要过多的依赖运算的优先级来控制表达式的执行顺序,这样可读性太差,尽量
使用小括号()来控制
表达式的执行顺序。 -
不要把一个表达式写得过于复杂,如果一个表达式过于复杂,则把它
分成几步
来完成。例如:
(num1 + num2) * 2 > num3 && num2 > num3 ? num3 : num1 + num2;
-
十一、标点符号
Java语言中列出的50个关键字(含保留字)和3个特殊值的单词(true、false、null)具有特殊意义;定义了38个运算符对应具体的运算指令;
Java规范中还规定了下画线_
和美元符号$
2个字符可以出现在标识符中,而斜线字符\
字符用作转义。除此之外,Java语言还包含了12个标点符号,如表所示。
( | ) | { | } | [ | ] |
---|---|---|---|---|---|
; | , | . | … | @ | :: |
- 小括号
()
用于强制类型转换、表示优先运算表达式、方法参数列表。 - 大括号
{}
用于数组元素列表、类体、方法体、复合语句代码块边界符。 - 中括号
[]
用于数组。 - 分号
;
用于结束语句。 - 逗号
,
用于多个赋值表达式的分隔符和方法参数列表分隔符。 - 英文句号
.
用于成员访问和包目录结构分隔符。 - 英文省略号
...
用于可变参数。 @
用于注解。- 双冒号
::
用于方法引用。
十二、【拓展】字符集
1、 字符集
- 编码与解码
计算机中储存的信息都是用二进制数
表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数转换之后的结果。按照某种规则,将字符存储到计算机中,称为编码
。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码
。
-
字符编码(Character Encoding) : 就是一套自然语言的字符与二进制数之间的对应规则。
-
字符集:也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。
2、ASCII码
- ASCII码(American Standard Code for Information Interchange,美国信息交换标准代码):上个世纪60年代,美国制定了一套字符编码,对
英语字符
与二进制位之间的关系,做了统一规定。这被称为ASCII码。 - ASCII码用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)。
- 基本的ASCII字符集,使用7位(bits)表示一个字符(最前面的1位统一规定为0),共
128个
字符。比如:空格“SPACE”是32(二进制00100000),大写的字母A是65(二进制01000001)。 - 缺点:不能表示所有字符。
3、ISO-8859-1字符集
- 拉丁码表,别名Latin-1,用于显示欧洲使用的语言,包括荷兰语、德语、意大利语、葡萄牙语等
- ISO-8859-1使用单字节编码,兼容ASCII编码。
4、GBxxx字符集
- GB就是国标的意思,是为了
显示中文
而设计的一套字符集。 - GB2312:简体中文码表。一个小于127的字符的意义与原来相同,即向下兼容ASCII码。但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合了包含
7000多个简体汉字
,此外数学符号、罗马希腊的字母、日文的假名们都编进去了,这就是常说的"全角"字符,而原来在127号以下的那些符号就叫"半角"字符了。 - GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了
双字节
编码方案,共收录了21003个
汉字,完全兼容GB2312标准,同时支持繁体汉字
以及日韩汉字等。 - GB18030:最新的中文码表。收录汉字
70244个
,采用多字节
编码,每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字,同时支持繁体汉字以及日韩汉字等。
5、Unicode码
-
Unicode编码为表达
任意语言的任意字符
而设计,也称为统一码、标准万国码。Unicode 将世界上所有的文字用2个字节
统一进行编码,为每个字符设定唯一的二进制编码,以满足跨语言、跨平台进行文本处理的要求。 -
Unicode 的缺点:这里有三个问题:
- 第一,英文字母只用一个字节表示就够了,如果用更多的字节存储是
极大的浪费
。 - 第二,如何才能
区别Unicode和ASCII
?计算机怎么知道两个字节表示一个符号,而不是分别表示两个符号呢? - 第三,如果和GBK等双字节编码方式一样,用最高位是1或0表示两个字节和一个字节,就少了很多值无法用于表示字符,
不够表示所有字符
。
- 第一,英文字母只用一个字节表示就够了,如果用更多的字节存储是
-
Unicode在很长一段时间内无法推广,直到互联网的出现,为解决Unicode如何在网络上传输的问题,于是面向传输的众多 UTF(UCS Transfer Format)标准出现。具体来说,有三种编码方案,UTF-8、UTF-16和UTF-32。
6、UTF-8
- Unicode是字符集,UTF-8、UTF-16、UTF-32是三种
将数字转换到程序数据
的编码方案。顾名思义,UTF-8就是每次8个位传输数据,而UTF-16就是每次16个位。其中,UTF-8 是在互联网上使用最广
的一种 Unicode 的实现方式。 - 互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。所以,我们开发Web应用,也要使用UTF-8编码。UTF-8 是一种
变长的编码方式
。它可以使用 1-4 个字节表示一个符号它使用一至四个字节为每个字符编码,编码规则:- 128个US-ASCII字符,只需一个字节编码。
- 拉丁文等字符,需要二个字节编码。
- 大部分常用字(含中文),使用三个字节编码。
- 其他极少使用的Unicode辅助字符,使用四字节编码。
- 举例
Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
————————————————————|—–—–—–—–—–—–—–—–—–—–—–—–—–—–
0000 0000-0000 007F | 0xxxxxxx(兼容原来的ASCII)
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7、 小结
注意:在中文操作系统上,ANSI(美国国家标准学会、AMERICAN NATIONAL STANDARDS INSTITUTE: ANSI)编码即为GBK;在英文操作系统上,ANSI编码即为ISO-8859-1。
十三、【拓展】进制
计算机世界中只有二进制,所以计算机中存储和运算的所有数据
都要转为二进制
。包括数字、字符、图片、声音、视频等。
1、进制的分类
- 十进制(decimal)
- 数字组成:0-9
- 进位规则:满十进一
- 二进制(binary)
- 数字组成:0-1
- 进位规则:满二进一,以
0b
或0B
开头
- 八进制(octal):很少使用
- 数字组成:0-7
- 进位规则:满八进一,以数字
0
开头表示
- 十六进制
- 数字组成:0-9,a-f
- 进位规则:满十六进一,以
0x
或0X
开头表示。此处的 a-f 不区分大小写
代码演示:
class BinaryTest {
public static void main(String[] args) {
int num1 = 123; //十进制
int num2 = 0b101; //二进制
int num3 = 0127; //八进制
int num4 = 0x12aF; //十六进制
System.out.println(num1);
System.out.println(num2);
System.out.println(num3);
System.out.println(num4);
}
}
2、进制换算表
十进制 | 二进制 | 八进制 | 十六进制 |
---|---|---|---|
0 | 0 | 0 | 0 |
1 | 1 | 1 | 1 |
2 | 10 | 2 | 2 |
3 | 11 | 3 | 3 |
4 | 100 | 4 | 4 |
5 | 101 | 5 | 5 |
6 | 110 | 6 | 6 |
7 | 111 | 7 | 7 |
8 | 1000 | 10 | 8 |
9 | 1001 | 11 | 9 |
10 | 1010 | 12 | a或A |
11 | 1011 | 13 | b或B |
12 | 1100 | 14 | c或C |
13 | 1101 | 15 | d或D |
14 | 1110 | 16 | e或E |
15 | 1111 | 17 | f或F |
16 | 10000 | 20 | 10 |
3、二进制
(1)二进制由来
-
二进制,是计算技术中广泛采用的一种数制,由德国数理哲学大师
莱布尼茨
于1679年发明。 -
二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“
逢二进一
”。 -
二进制广泛应用于我们生活的方方面面。比如,广泛使用的摩尔斯电码(Morse Code),它由两种基本信号组成:短促的点信号“
·
”,读“滴
”;保持一定时间的长信号“—
”,读“嗒
”。然后,组成了26个字母,从而拼写出相应的单词。
记忆技巧:
例子:
(2)在计算机中二进制如何表示整数?
-
存储形式:
计算机数据的存储使用二进制
补码
形式存储,并且最高位是符号位
。
- 正数:
最高位是0
- 负数:
最高位是1
- 规 定:
正数的补码与反码、原码一样,称为
三码合一
负数的补码与反码、原码不一样:
负数的
原码
:把十进制转为二进制,然后最高位设置为1负数的
反码
:在原码的基础上,最高位不变,其余位取反(0变1,1变0)负数的
补码
:反码+1例如:
正数:25 00000000 00000000 000000000 00011001(原码) 正数:25 00000000 00000000 000000000 00011001(反码) 正数:25 00000000 00000000 000000000 00011001(补码) 负数:-25 10000000 00000000 000000000 00011001(原码) 负数:-25 11111111 11111111 111111111 11100110(反码) 负数:-25 11111111 11111111 111111111 11100111(补码)
- tips:
为什么用32位表示?
数据类型占内存的位数与操作系统的位数和编译器都有关
一个字节可以存储的整数(int)范围是多少?
范围是:-128~127
1个字节:8位 2^7=128 (最高位为符号位)0000 0001 ~ 0111 111 ==> 1~127 1000 0001 ~ 1111 1111 ==> -127 ~ -1 0000 0000 ==>0 1000 0000 ==> -128(特殊规定)=-127-1
4、二进制转十进制
方法:权相加法
针对于byte数据举例来说:
5、十进制转二进制
方法:除2取余的逆
6、二进制与八进制、十六进制间的转换
-
二进制转八进制
-
二进制转十六进制
-
八进制、十六进制转二进制
-
各进制间的转换方式