Java基本语法
- 1、关键字与保留字
- 关键字的定义和特点
- 保留字的定义
- 2、标识符
- 标识符的定义
- 定义合法标识符规则
- Java中的名称命名规范
- 3、变量
- 变量的概念
- 变量的作用
- 使用变量注意
- 变量的分类
- 整数变量:byte、short、int、long
- 浮点类型:float、double
- 字符类型:char
- 布尔型:boolean
- 基本数据类型转换
- 强制类型转换
- 字符串类型:String
- 4、进制
- 5、运算符
- 算术运算符
- 赋值运算符
- 比较运算符
- 逻辑运算符
- 位运算符
- 三元运算符
- 6、程序流程控制
- 分支结构
- 循环结构
- 7、数组
- 附加:Arrays工具类的使用
1、关键字与保留字
关键字的定义和特点
- 被Java语言赋予了特殊含义,用做专门用途的字符串(单词)
- 关键字中所有字母都为小写
保留字的定义
- 现有Java版本尚未使用,但以后版本可能会作为关键字使用。命名标识符时要避免使用这些保留字。
总结:48个关键字、2个保留字、3个字面值
用于定义数据类型的关键字
class interface enum byte short int long float double char boolean void
用于定义流程控制的关键字
if else switch case default while do for break continue return
用于定义访问权限修饰符的关键字
private protected public
用于定义类,函数,变量修饰符的关键字
abstract final static synchronized
用于定义类与类之间关系的关键字
extends implements
用于定义建立实例及引用实例,判断实例的关键字
new this super instanceof
用于异常处理的关键字
try catch finally throw throws
用于包的关键字
package import
其他修饰符关键字
native strictfp transient volatile assert
保留字
goto const
用于定义数据类型值的字面值
true false null true
2、标识符
标识符的定义
- Java对各种变量、方法和类等要素命名时使用的字符序列称为标识符
技巧:凡是自己可以起名字的地方都叫标识符
定义合法标识符规则
- 由26个英文字母大小写,0-9,_或$组成
- 数字不可以开头
- 不可以使用关键字和保留字,但能包含关键字和保留字
- Java中严格区分大小写,长度无限制
- 标识符不能包含空格
Java中的名称命名规范
- 包名:多单词组成时所有字母都小写:xxxyyyzzz
- 类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz
- 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
- 常量名:所有字母都大写,多单词时每个单词用下划线连接:XXX_YYY_ZZZ
注意点:
1、在起名字时,为了提高阅读性,要尽量有意义,“见名知意”。
2、Java采用unicode字符集,因此标识符也可以使用汉字声明,但是不建议使用。
3、变量
变量的概念
- 内存中的一个存储区域
- 该区域的数据可以在同一类型范围内不断变化
- 变量是程序中最基本的存储单元,包含变量类型、变量名、存储的值
变量的作用
- 用于在内存中保存数据
使用变量注意
- Java中每个变量必须先声明,后使用
- 使用变量名来访问这块区域的数据
- 变量的作用域:其定义所在的一对{}内
- 变量只有在其作用域内才有效
- 同一个作用域内,不能定义重名的变量
变量的分类
按数据类型分类
- 基本数据类型
- 数值型
- 整数类型 (byte short int long)
- 浮点类型 (float double)
- 字符型 (char)
- 布尔型 (boolean)
- 数值型
- 引用数据类型
- 类 (class)
- 接口 (interface)
- 数组 ([])
按声明位置分类
- 成员变量
- 实例变量 (不以static修饰)
- 类变量 (以static修饰)
- 局部变量
- 形参 (方法、构造器中定义的变量)
- 方法局部变量 (在方法内部定义)
- 代码块局部变量 (在代码块内定义)
整数变量:byte、short、int、long
- Java各整数类型有固定的表数范围和字段长度,不受具体OS的影响,以保证Java程序的可移植性。
- Java的整型常量默认为int型,声明long型常量须加
l
或者L
- Java程序中变量通常声明为int型,除非不足以表示较大的数,才使用long
类型 | 占用存储空间 | 表数范围 |
---|---|---|
byte | 1字节=8bit位 | -128~127 |
short | 2字节 | - 2 15 2^{15} 215~ 2 15 2^{15} 215-1 |
int | 4字节 | - 2 31 2^{31} 231~ 2 31 2^{31} 231-1(约21亿) |
long | 8字节 | - 2 63 2^{63} 263~ 2 63 2^{63} 263-1 |
bit:计算机中的最小存储单位。byte:计算机中基本存储单元。
浮点类型:float、double
- 与整数类型类似,Java浮点类型也有固定的表数范围和字段长度,不受具体操作系统的影响
- 浮点型常量有两种表示形式:
- 十进制数形式
- 科学计数法形式
- float:单精度,尾数可以精确到7位有效数字。很多情况下,精度很难满足需求。
- double:双精度,精度是float的两倍。通常采用此类型。
- Java的浮点型常量默认是double型,声明float型常量,须后加
f
或F
。
类型 | 占用存储空间 | 表数范围 |
---|---|---|
float | 4字节 | -3.403E38~3.403E38 |
double | 8字节 | -1.798E308~1.798E308 |
注意点:float表示数值的范围比long还大
float数值的范围怎么计算?
根据IEEE754标准,划分符号位、指数位,有效数字位进行计算。
字符类型:char
- char型数据用来表示通常意义上“字符”(2字节)
- Java中所有字符都使用Unicode编码,故一个字符可以存储一个字母,一个汉字,或其他书面语的一个字符。
- 字符型变量的三种表现形式:
- 字符常量是用单引号’'括起来的单个字符。
- Java中还允许使用转义字符’\'来将其后的字符转变为特殊字符型常量。
- 直接使用Unicode值来表示字符型常量。
- char类型是可以进行运算的。因为它都对应有Unicode编码。
char c1 = 'a'; // 编译通过
// char c2 = 'AB'; // 编译不通过
char c3 = '中'; // 编译通过
char c4 = '\n'; // 编译通过
char c5 = '\u0043'; // 编译通过
// char c6 = ''; // 编译不通过
char c7 = 97; // a, 开发中极其少见
常用ASCII码值: ‘a’ == 97; ‘A’ == 65;
布尔型:boolean
- 只能取两个值之一:true、false
- 常常在条件判断、循环结构中使用
基本数据类型转换
- 自动类型转换:容量小的类型自动转换为容量大的数据类型。数据类型按容量大小排序为:
char、byte、short --> int --> long --> float --> double
- 有多种类型的数据混合运算时,系统首先自动将所有数据类型转换为容量最大的那种数据类型,然后再进行计算
- byte,short,char之间不会互相转换,他们三者在计算时首先转换为int类型
Java在做运算的时候,如果操作数均在int范围内,那么一律在int的空间内运算。
- boolean类型不能与其它数据类型运算
- 当把任何基本数据类型的值和字符串(String)进行连接运算时(+),基本数据类型的值将自动转化为字符串(String)类型
说明:此时的容量大小指的是表示数的范围的大小。比如:float容量要大于long的容量
强制类型转换
- 自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转换符:
()
,但可能造成精度降低或溢出,格外要注意
double d1 = 12.9;
int i1 = (int)d1; // 12,截断操作
int i2 = 128;
byte b = (byte)i2; // -128
- 通常,字符串不能直接转换为基本类型,但通过基本类型对应的包装类则可以实现把字符串转换为基本类型
String a = "43";
int i = Integer.parseInt(a);
- boolean类型不可以转换为其它的数据类型
说明:整型常量,默认类型是int型;浮点型常量,默认类型是double型。
byte b = 12;
// byte b1 = b + 1; // 编译失败
// float f1 = b + 12.3; // 编译失败
字符串类型:String
- String不是基本数据类型,属于引用数据类型
- 使用方式与基本数据类型一致。
- 一个字符串可以串接另一个字符串,也可以直接串接其他类型的数据。
String str = "abcd";
str = str + "xyz";
int n = 100;
str = str + n; // abcdxyz100
4、进制
- 所有数字在计算机底层都是以二进制形式存在。
- 对于整数,有四种表示方式:
- 二进制(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不区分大小写。
- 二进制(binary):0,1,满2进1,以
- Java整数常量默认是int类型,当用二进制定义整数时,其第32位(最高位)是符号位:当是long类型时,二进制默认占64位,第64位是符号位
- 二进制的整数有如下三种形式:
- 原码:直接将一个数值换成二进制数。最高位是符号位(0负1正)
- 负数的反码:是对原码按位取反,只有最高位(符号位)确认为1
- 负数的补码:其反码加1
- 计算机以二进制补码的形式保持所有的整数
- 正数的原码、反码、补码都相同
- 负数的补码是其反码+1
5、运算符
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。
- 算术运算符
- 赋值运算符
- 比较运算符(关系运算符)
- 逻辑运算符
- 位运算符
- 三元运算符
算术运算符
运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
+ | 正号 | +3 | 3 |
- | 负号 | b=4; -b | -4 |
+ | 加 | 5+5 | 10 |
- | 减 | 6-4 | 2 |
* | 乘 | 3*4 | 12 |
/ | 除 | 5/5 | 1 |
% | 取模(取余) | 7%5 | 2 |
++ | 自增(前),先运算后取值 | a=2;b=++a; | a=3;b=3 |
++ | 自增(后),先取值后运算 | a=2;b=a++; | a=3;b=2 |
– | 自减(前),先运算后取值 | a=2;b=–a; | a=1;b=1 |
– | 自减(后),先取值后运算 | a=2;b=a–; | a=1;b=2 |
+ | 字符串连接 | “He”+“llo” | “Hello” |
疑难点1:%
取余运算,结果的符号与被模数的符号相同
int m1 = 12;
int n1 = 5;
System.out.println("m1 % n1 = " + m1 % n1); // m1 % n1 = 2
int m2 = -12;
int n2 = 5;
System.out.println("m1 % n1 = " + m2 % n2); // m1 % n1 = -2
int m3 = 12;
int n3 = -5;
System.out.println("m1 % n1 = " + m3 % n3); // m1 % n1 = 2
int m4 = -12;
int n4 = -5;
System.out.println("m1 % n1 = " + m4 % n4); // m1 % n1 = -2
疑难点2:++ 和 – 不会改变变量本身的数据类型
short s = 10;
//s = s + 1; //编译失败
s = (short) (s + 1); //正确
s++; //正确
byte b = 127;
b++;
System.out.println(b); //-128
赋值运算符
符号:=
拓展赋值运算符:+=
,-=
,*=
,/=
,%=
- 当
=
两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理 - 支持连续赋值
int i, j;
//连续赋值
i = j = 10;
疑难点:拓展赋值运算符不会改变变量本身的数据类型
short s = 10;
//s = s + 2; //编译失败
s += 2;
System.out.println(s); //12
int i = 1;
i *= 0.1;
System.out.println(i); // 0
比较运算符
运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
== | 相等于 | 4==3 | false |
!= | 不等于 | 4!=3 | true |
< | 小于 | 4<3 | false |
> | 大于 | 4>3 | true |
<= | 小于等于 | 4<=3 | false |
>= | 大于等于 | 4>=3 | true |
instanceof | 检查是否是类的对象 | “Hello” instanceof String | true |
- 比较运算符的结果都是boolean型,也就是要么是true,要么是false。
- 比较运算符
==
不能误写成=
>
<
>=
<=
:只能使用在数值类型的数据之间==
:不仅可以使用在数值类型数据之间,还可以使用在其他引用类型变量之间。
逻辑运算符
&
-逻辑与
|
-逻辑或
!
-逻辑非
&&
-短路与
||
-短路或
^
-逻辑异或
a | b | a&b | a&&b | a|b | a||b | !a | a^b |
---|---|---|---|---|---|---|---|
true | true | true | true | true | true | false | false |
true | false | false | false | true | true | false | true |
false | true | false | false | true | true | true | true |
false | false | false | false | false | false | true | false |
区分 & 与 &&
- 相同点1:&与&&的运算结果相同
- 相同点2:当符号左边为true时,二者都会执行符号右边的运算
- 不同点:当符号左边为false时,&继续执行符号右边的运算,&&不再执行符号右边的运算
区分 | 与 ||
- 相同点1:|与||的运算结果相同
- 相同点2:当符号左边是false时,二者都会执行符号右边的运算
- 不同点1:当符号左边是true时,|继续执行符号右边的运算,而||不再执行符号右边的运算
位运算符
运算符 | 运算 | 范例 |
---|---|---|
<< | 左移 | 3 << 2 = 12 --> 3*2*2=12 |
>> | 右移 | 3 >> 1 = 1 --> 3/2=1 |
>>> | 无符号右移 | 3 >>> 1 = 1 --> 3/2=1 |
& | 与运算 | 6 & 3 = 2 |
| | 或运算 | 6 | 3 = 7 |
^ | 异或运算 | 6 ^ 3 = 5 |
~ | 取反运算 | ~6 = -7 |
位运算时直接对整数的二进制进行的运算
运算符 | 描述 |
---|---|
<< | 空位补0,被移除的高位丢弃,空缺位补0 |
>> | 被移除的二进制最高位是0,右移后,空缺位补0,若最高位是1,空缺位补1 |
>>> | 被移位二进制最高位无论是0或者是1,空缺位都用0补 |
& | 二进制位进行&运算,只有1&1时结果是1,否则是0 |
| | 二进制位进行|运算,只有0|0时结果是0,否则是1 |
^ | 相同二进制进行^运算结果是0:1^1=0,0^0=0;不相同二进制位^运算结果是1:1^0=1,0^1=1 |
~ | 各二进制码按补码各位取反 |
m = k ^ n = (m ^ n) ^ n
三元运算符
- 格式:(条件表达式) ? 表达式1 : 表达式2;
- 表达式1和表达式2为同种类型
三元运算符与if-else的联系与区别
- 三元运算符可简化if-else语句
- 三元运算符要求必须返回一个结果
- if后的代码块可有多个语句
附加:运算符的优先级
. () {} ; , | |
---|---|
R–>L | ++ -- ~ !(data type) |
L–>R | * / % |
L–>R | + - |
L–>R | << >> >>> |
L–>R | < > <= >= instanceof |
L–>R | == != |
L–>R | & |
L–>R | ^ |
L–>R | | |
L–>R | && |
L–>R | || |
R–>L | ? : |
R–>L | = *= /= %= |
+= -= <<= >>= | |
>>>= &= ^= |= |
6、程序流程控制
- 程序控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。
- 其流程控制方式采用结构化程序设计中规定的三种基本流程结果,即:顺序结构、分支结构、循环结构
分支结构
if-else结构
- else 结构是可选的
- 针对与条件表达式:
- 如果多个条件表达式之间是“互斥”关系(或没有交集的关系),哪个判断和执行语句声明在上面还是下面,无所谓。
- 如果多个条件表达式之间有交集的关系,需要根据实际情况,考虑清楚应该将哪个结构声明在上面。
- 如果多个条件表达式之间有包含关系,通常情况下,需要将范围小的声明在范围大的上面。否则,范围小的就没有机会执行
- if-else 结构是可以互相嵌套的。
- 如果if-else结构中的执行语句只有一行时,对应的一对{}可以省略的。但是,不建议大家省略。
- 多个if-else时,if-else的配对方式采用就近原则进行配对
switch-case结构
switch(表达式){
case 常量1:
语句1;
// break;
case 常量2:
语句2;
// break;
... ...
case 常量N:
语句N;
// break;
default:
语句;
// break;
}
- 根据switch表达式中的值,依次匹配各个case中的常量。一旦匹配成功,则进入相应的case结构中,调用其执行语句。当调用完执行语句以后,则仍然继续向下执行其他case结构中的执行语句,直到遇到break关键字或此switch-case结构末尾结束为止。
- break,可以使用在switch-case结构中,表示一旦执行到此关键字,就跳出switch-case结构
- switch结构中的表达式,只能是如下的6种数据类型之一:byte、short、char、int、枚举类型(JDK5.0新增)、String类型(JDK7.0新增)
- case 之后只能声明常量,不能声明范围。
- break 关键字是可选的
- default:相当于if-else结构中的else。default结构是可选的,而且位置是灵活的。
int number = 0;
// Console: zero
switch(number) {
default:
System.out.println("other");
case 0:
System.out.println("zero");
break;
case 1:
System.out.println("one");
break;
}
- 凡是可以使用switch-case的结构,都可以转换为if-else。反之,不成立。
- 当发现既可以使用switch-case且switch中表达式的取值情况不太多,又可以使用if-else时,我们优先选择使用switch-case。原因:switch-case执行效率稍高。
循环结构
循环语句的四个组成部分
- 初始化部分
- 循环条件部分
- 循环体部分
- 迭代部分
for循环结构
for(初始化部分;循环条件部分;迭代部分) {
循环体部分
}
执行过程:初始化部分-循环条件部分-循环体部分-迭代部分-循环条件部分-循环体部分-迭代部分- ... - 循环条件部分
while循环结构
初始化部分
while(循环条件部分) {
循环体部分
迭代部分
}
执行过程:初始化部分-循环条件部分-循环体部分-迭代部分-循环条件部分-循环体部分-迭代部分- ... - 循环条件部分
- 写while循环千万小心不要丢了迭代条件。一旦丢了,就可能导致死循环!
- 写程序需要避免出现死循环。
- for循环和while循环是可以相互转换的。区别在于for循环和while循环的初始化条件部分的作用范围不同。
do-while循环结构
初始化部分
do{
循环体部分
迭代部分
}while(循环条件部分);
执行过程:初始化部分-循环体部分-迭代部分-循环条件部分-循环体部分-迭代部分- ... - 循环条件部分
- do-while循环至少会执行一次循环体!
- 开发中,使用for和while更多一些。较少使用do-while
特殊关键字的使用
适用范围 | 不同点 | 相同点 | |
---|---|---|---|
break | switch-case和循环结构中 | 结束当前循环 | 关键字后面不能声明执行语句 |
continue | 循环结构中 | 结束当次循环 | 关键字后面不能声明执行语句 |
label: for(int i = 1; i <= 4; i++) {
for(int j = 1; j <= 10; j++) {
if (j % 4 == 0) {
//break; //默认跳出包裹此关键字最近的一层循环
//continue;
//break label; //结束指定标识的一层循环结构
continue label; //结束指定标识的一层循环结构当次循环
}
}
}
- return:并非专门用于结束循环的,它的功能是结束一个方法。当一个方法执行到一个return语句时,这个方法将被结束。
- 与break和continue不同的是,return直接结束整个方法,不管这个return处于多少层循环之内
7、数组
- 数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
- 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
- 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
- 数组的长度一旦确定,就不能修改。
//1.一维数组的声明和初始化
int[] ids;//声明
//1.1静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[]{1001,1002,1003,1004};
//1.2动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
数组元素的默认初始化值
- 数组元素是整型:0
- 数组元素是浮点型:0.0
- 数组元素是char型:0或者’\u0000’,而非’0’
- 数组元素是boolean型:false
- 数组元素是引用数据类型:null
对于二维数组的理解:我们可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。其实,从数组底层的运行机制来看,其实没有多维数组。
//一些错误的写法
//int[] ids;
//ids = {1,2,2}; //编译错误
//一些正确但是不标准的写法
int[] arr1 = {1,2,2,3}; //类型推断
int[] arr2[] = new int[][]{{1,2,2},{4,5},{6,7,8}}; // 数组[]位置可以随意
int[] arr3[] = {{1,2,2},{4,5},{6,7,8}};
String[] strArray1[] = {{"222", "2222"},{"111", "3333", "5555"}};
附加:Arrays工具类的使用
- java.util.Arrays类即为操作数组的工具类,包含了用来操作数组的各种方法
方法 | 作用 |
---|---|
boolean equals(int[] a,int[] b) | 判断两个数组是否相等 |
String toString(int[] a) | 输出数组信息 |
void fill(int[] a,int val) | 将指定值填充到数组之中 |
void sort(int[] a) | 对数组进行排序 |
int binarySearch(int[] a,int key) | 对排列后的数组进行二分法检索指定的值 |