Java语言基础
1,基本语言要素
(1)关键字
java关键字(也称为保留字)是指那些具有特定定义和专门用途的单词,它们不能被用作标识符。java关键字共计53个(java的官方文档认为字面常量true,false,null不是关键字,因此官方认定的关键字是50个)。按其作用可以分为以下几类:
java语言关键字分类列表
关键字分类 | 关键字数量 | 关键字列表 |
数据类型 | 9 | boolean,byte,char,short,int,long,float,double,void |
字面常量 | 3 | true,false,null |
流程控制 | 11 | for,if,else,while,do,switch,case,default,break,continue,return |
访问范围修饰符 | 3 | public,private,protected |
其他修饰 | 7 | final,static,abstract,synchronized,transient,native,volatile |
类、接口和包 | 6 | class,interface,package,implements,extends,import |
对象相关 | 4 | new,this,super,instanceOf |
异常处理 | 5 | try,catch,finally,throw,throws |
1.0后版本新增 | 3 | enum,strictfp,assert |
保留不用 | 2 | goto,const |
(2)标识符
标识符是用来表示常量、变量、标号、方法、类、接口以及包的名字。
1)命名规则
标识符的命名规则如下:
●只能使用字母、数字、下划线和美元符。
●只能以字母、下划线和美元符开头,不能用数字开头。
●严格区分大小写,没有长度限制。
●不能使用java关键字。
由于java语言内置了对Unicode字符编码的支持,因此中文字符也是字母,允许使用中文作为标识符,但强烈反对用中文作为标识符。
非法标识符举例:
①数字起头:12Programe
②含有非法字符:java&project
③含有空格:$Program java
④含有java关键字:class等
2)命名规范
标识符的命名规范如下:
●标识符用英语单词,尽量使用完整的单词,尽量不使用缩写。可以是一个或多个单词,应该具有合适的含义,这样的代码具有自我说明的功能。
●标识符中不使用美元符和下划线(下划线只在常量名中使用),尽量只使用字母,必要时才少量使用数字。美元符和下划线可能会用在某些特殊场合中。
●不要使用常用的类名以及内部使用的常用名称,如String java等,如果使用了这样的标识符,在有些情况下则可能引起编译出错,也可能是程序不能正常执行。
●通过标识符中的大小写区分不同类型的标识符,其规则如下:
------常量名:全部用大写字母。如果由多个单词组成,则使用下划线分隔单词,例如PI、MAX_VALUE
------变量名:用小写字母。如果由多个单词组成,则从第二个单词起的单词首字母大写。例如file 、fileName
------方法名:用小写字母。如果由多个单词组成,则从第二个单词起的单词首字母大写。方法名的第一个单词常常是动词。例如add 、readConfigFile。
------类名:首字母大写,其余用小写。如果由多个单词组成,则从第二个单词起的单词首字母大写。例如 User 、 UserDao。
------接口名:首字母大写,其余用小写。如果由多个单词组成,则从第二个单词起的单词首字母大写。例如 User、 UserDao。有时可能在前面加字符“I”,表示它是一个接口,例如IUser。但在一个项目中应该达成统一共识。
------包名:全部用小写字母。如果由多个单词组成,则使用半角的句点“.”分隔单词,例如com.amychris.dao。句点不是标识符中可用的字符,只是用在包名的分隔符中。
(3)分隔符
java语言的分隔符用于分隔标识符和关键字,共有7种,即空格、句号、分号、逗号、圆括号、方括号和花括号。
待续……
(4)注释
java语言的注释有3种,即单行注释、多行注释和文档注释。
待续……
2,数据类型
(1)java 语言数据类型
1,java语言的数据类型如图所示:
注意:
●空类型(void)是一个数据类型的占位符,它表示没有类型,仅用于方法返回值类型的声明上。空(null)不是类型,而是一个字面常量,它表示没有值,用于表示引用数据类型的值为空。
●字符串(string)类型是一种引用数据类型,但它是唯一一种具有某些基本数据类型特征的引用数据类型。
(2),常量和变量
常量和变量用来表示java程序中的数据。常量是指程序执行过程中始终不变的量,而变量则是根据执行的情况,可以改变值的量。
(1)常量
常量有字面常量和字符常量两种。
待续……
(2)变量
变量用来于标识数据的存储单元。
1)声明变量的一般格式如下:
[变量修饰符] 数据类型 变量名 [=初始值];
2)java语言中的变量根据作用域范围的不同,可分为4种:
成员变量:在类中声明,但是在方法之外,因此作用域范围是整个类。
局部变量:在语句块内声明,作用域范围是从声明处直到该语句块的结束。
方法参数变量:在方法内声明,作用域范围是在整个方法中。
异常处理参数变量:作用域范围是在异常处理语句块中。
3)关于变量的问题
1,成员变量、局部变量和方法参数变量的区别,用代码说明。
2,成员变量与局部变量的区别
待续……
4)使用变量时要注意的几个方面
局部变量的使用要遵循先声明后使用的原则。
一个好的编程习惯是在声明一个变量的同时对它进行初始化。
变量命名规范。
与c++相比较,c/c++中存在全局变量,而在java中没有全局变量。
3,运算符
(1),算术运算符
使用算术运算符时需要注意如下几个方面。
进行二元运算符时,如果两个操作数的类型不同,将会自动进行类型转换。
(2),关系运算符
使用关系运算符时需要注意如下几个方面
- 对于字符进行比较时,实质上是对字符所代表的Unicode码进行比较。
- 不应该对字符串进行比较,字符串的比较有专门的方法。
ASCII码表
(3),布尔运算符
(4),位运算符
(5),类型比较运算符
关键字instanceOf用于比较一个变量的值是否属于某种类型(即一个对象的值是否是某个类的实例instance)
(6),条件运算符
条件运算符的一般形式如下:
表达式1 ?表达式2:表达式3;
当表达式1为真时,条件表达式返回表达式2的值;否则返回表达式3的值。
例如:
double salary=(x instanceOf Teacher)? 3000:2000;
(7),字符串连接运算符
(8),赋值运算符
(9),运算符的优先级
(10)关于运算符的相关问题
1),普通与&和简洁与&&的区别
普通与&和简洁与&&的区别在于,如果运算符的第一个表达式的值为false,那么,这时可以断定运算结果为false,因此简洁与&&将直接返回结果,而普通与&还将进行第二个表达式的求值。虽然二者返回的结果相同,但普通与&对第二个表达式进行了运算,将能够实现第二个表达式求值过程中所完成的附加功能。
2),普通或|和简洁或||的区别
普通或|和简洁或||的区别在于,如果运算符的第一个表达式的值为true,那么,这时可以断定运算结果为true,因此简洁或 || 将直接返回结果,而普通或 | 还将进行第二个表达式的求值。虽然二者返回的结果相同,但普通或 | 对第二个表达式进行了运算,将能够实现第二个表达式求值过程中所完成的附加功能。
4,控制结构
(1)顺序结构
顺序结构是指程序从上向下依次执行每条语句的结构,中间没有任何的判断和跳转。这样的结构就是顺序结构。
(2)选择结构
选择结构也称为条件结构、分支结构。
选择结构是根据条件判断的结果来选择执行不同的代码。选择结构可以细分为单分支结构、双分支结构和多分支结构。在java语言提供了if控制语句和switch语句来实现选择结构。
1)if控制语句
if控制语句共有3种不同的形式,分别是单分支结构、双分支结构和多分支结构。
1,使用if语句实现单分支处理
if语句的语法:
if(表达式){
语句
}
在语法中:(1)if是java关键字。(2)表达式是布尔类型的表达式,其结果为true或false。
if语句的流程图
if语句的执行步骤:
(1)对表达式的结果进行判断。
(2)如果表达式的结果为真,则执行语句。
(3)如果表达式的结果为假,则跳过该语句。
2,使用if-else语句实现双分支处理
if-else语句的语法:
if(表达式){
语句 1
} else{
语句2
}
if-else语句的流程图:
if-else语句的执行步骤:
(1)对表达式的结果进行判断。
(2)如果表达式的结果为true,则执行语句1。
(3)如果表达式的结果为false,则执行语句2。
3,使用多分支if语句实现多分支处理
当条件判断有多个选择时,需要使用多分支if语句解决。
多分支if语句的语法:
if(表达式){
语句 1
} else if (表达式2){
语句2
} else{
语句3
}
多分支if语句的流程图
多分支if语句的执行步骤:
(1)对表达式1的结果进行判断。
(2)如果表达式1的结果为true,则执行语句1,否则,判断表达式2的值。
(3)如果表达式2的结果为true,则执行语句2,否则,执行语句3.
注意:
1,在上述3种if控制语句中,条件表达式的值必须是布尔类型,这是java语言与c、c++语言的不同之处。
2,语句可以是一条语句,也可以是多条语句。
嵌套if控制语句
在if控制语句中又包含一个或多个if控制语句称为嵌套if控制语句。嵌套if控制语句可以通过外层语句和内层语句的协作,增强程序的灵活性。
if(表达式1){
if(表达式 2){
语句1
}
else{
语句2
}
} else{
if(表达式3) {
语句3
}else{
语句4
}
}
嵌套if控制语句的流程图
嵌套if控制语句的执行步骤:
(1)对表达式1的结果进行判断。
(2)如果表达式1的结果为true,对表达式2的结果进行判断。如果表达式的结果为true,则执行语句1,否则,执行语句2。
(3)如果表达式1的结果为false,对表达式3的结果进行判断。如果表达式3的结果为true,则执行语句3,否则,执行语句4。
2)switch语句
java提供了switch语句,用于实现多分支选择结构,它和多分支if控制语句在某些情况下可以相互替代。
switch语句的语法:
switch(表达式){
case 常量1:
语句;
break;
case 常量2:
语句;
break;
……
default:
}
在语法中:
- switch、case、break、default是java关键字
- switch后的表达式只能是整型、字符型或枚举类型
- case 用于与表达式进行匹配
- break用于终止后续语句的执行
- default是可选的,当其他条件都不匹配时执行default
注意:如果case后没有break语句,程序将继续向下执行,直到遇到break语句或switch语句结束。
switch语句的流程图
switch语句的执行步骤:
(1)计算switch后表达式的值。
(2)将计算结果从上至下依次与case后的常量值比较
(3)如果相等就执行该常量后的代码块,遇到break语句就结束
(4)如果与任何一个case后的常量值都不匹配,就执行default中的语句
(3)循环结构
循环结构是根据条件来重复性地执行某段代码。在java中提供了while语句、do-while语句、for语句来实现循环结构。JDK5.0中新提供了增强型for循环,可以以更简单的方式来遍历数组和集合。
循环语句的主要作用是反复执行一段代码,直到满足一定的条件为止。可以把循环分成3个部分。
初始部分:设置循环的初始状态
循环体:重复执行的代码
循环条件:判断是否继续循环的条件,如使用“i<100”判断循环次数是否已经达到100次。
java语言提供4种循环结构,即当型循环、直到型循环、for循环和增强型for循环。
1.while循环(当型)
while循环语句的语法:
变量初始化;
while(循环体){
循环体
}
注意:while语句先判断循环条件再执行循环体,如果第一次判断循环条件为假,循环将一次也不执行。
当型循环的特点是循环体部分可能执行一次或多次,也可能一次都不执行。
while循环的执行图
while语句的执行步骤:
(1)首先对循环条件的结果进行判断,如果结果为真,则执行循环语句。
(2)执行完毕后继续对循环条件进行判断,如果为真,继续执行。
(3)如果结果为假,则跳过循环语句,执行后面的语句。
2,do-while循环
do-while循环语句的语法:
变量初始化
do{
循环体
}while(循环条件);
do-while语句的流程图:
do-while语句的执行步骤:
(1)首先执行循环体;
(2)执行完毕后对循环条件的结果进行判断。
(3)如果结果为真,则继续执行循环体。如果结果为假,终止循环,执行后面的语句。
注意:do-while语句先执行循环体再判断循环条件,所以循环体至少执行一次,这一点和while循环正好相反。
当型循环与直到型循环的区别如下:
while循环:有可能1次也不执行循环体。
do-while循环:至少执行1次循环体。
3,for循环
for循环语句的语法:
for(表达式1;表达式2,;表达式3){
循环体
}
或更直观地表示为
for(变量初始化;循环体;修改循环变量的值){
循环体
}
for语句的流程图:
for语句的执行步骤:
(1)首先执行表达式1,一般是进行变量初始化操作
(2)然后执行表达式2,即对循环条件进行判断。
(3)如果结果为真,则执行循环体。
(4)循环语句执行完毕后执行表达式3,改变循环变量的值,再次执行表达式2,结果为真,继续循环。
(5)如果结果为假,终止循环,执行后面的语句。
注意:无论循环多少次,表达式1只执行一次。
4,增强型for循环
增强型for循环是java5.0引入的。
增强型for循环的语法如下:
for(数据类型 变量:集合){
循环体部分;
}
5,多重循环
一个循环语句的循环体中还可以再包含循环语句,又称为嵌套循环。循环语句内可以嵌套多层循环。同时,不同的循环语句可以相互嵌套。
多重循环语句的语法:
while(循环条件1){
循环语句1
for(循环条件2){
循环语句2
}
}
以上是while和for语句嵌套的例子。其中while循环称为外层循环,for循环称为内层循环,因为是两层嵌套,所以称为二重循环。
该二重循环的执行过程是,外层while循环每循环一次,内层for循环就从头到尾完整地执行一遍。
6,循环对比
1)语法不同
while循环语句的语法:
变量初始化;
while(循环体){
循环体
}
do-while循环语句的语法:
变量初始化
do{
循环体
}while(循环条件);
for循环语句的语法:
for(表达式1;表达式2,;表达式3){
循环体
}
或更直观地表示为
for(变量初始化;循环体;修改循环变量的值){
循环体
}
2)执行顺序不同
while循环:先进行循环条件判断,再执行循环体。如果条件不成立,退出循环。
do-while循环:先执行循环体,再进行循环条件判断,循环体至少执行一次。
for循环:先执行变量初始化部分,再进行循环条件判断,然后执行循环体,最后进行循环变量的计算。如果条件不成立,跳出循环。
3)适用情况不同
在解决问题时,对于循环次数确定的情况下,通常选用for循环。对于循环次数不确定的情况,通常选用while循环和do-while循环。
4,使用跳转语句控制程序流程
java语言支持3种类型的跳转语句:break语句、continue语句和return语句。使用这些语句,可以把控制转移到循环甚至程序的其他部分。
1)break语句
break语句在循环中的作用是终止当前循环,在switch语句中的作用是终止switch。
break语句只会出现在switch和循环语句中,没有其他的使用场合。
2)continue语句
continue语句的作用是强制一个循环提前返回,也就是让循环跳出本次循环剩余代码,然后开始下一次循环。
在while和do-while循环中,continue执行完毕后,程序将直接判断循环条件,如果为true,继续下一次循环,否则,终止循环。而在for循环中,continue使程序先跳转到循环变量计算部分,然后再判断循环条件。
continue语句只会出现在循环语句中,它只有这一种使用场合。
3)return语句
return语句的作用是结束当前方法的执行并退出,返回调用该方法的语句处。
5,数组
数组是引用数据类型,用于存储一组相同类型的数据的集合。数组分为一维数组和二维数组。
(1)一维数组
1)一维数组的声明:
数据类型 数组名 []
数据类型 [] 数组名
声明数组时需要注意以下几点:
- 数组的所有元素具有相同的数据类型
- 声明数组时,不能在方括号中指定数组的元素个数,如int[10] score。
- 声明数组而没有对其他初始化就直接使用,将会出现编译错误。
2)一维数组的创建(初始化)
数组名 = new 数据类型 [数组长度];
数组长度:数组可以存储的元素的个数。
一些数组初始化的例子:
averageScore=new float [40];
int [] score=new int[6];
String [] name=new String[6];
可以将数组的声明和初始化写在一起,使用时需要注意以下几点:
- 数据类型可以是基本数据类型和引用数据类型,但等号前后的类型必须保持一致。
- 数组的长度一旦设置,即分配了内存空间,其大小就再也不能改变了。
- 数组的长度确定以后,其长度值被保存在数组的length属性中,该属性时final的、不可改变的(即常量)。
- 分配空间时,将每个元素初始化为默认值,数值类型的默认值为0,布尔型的为false,字符型的为'\u0000',引用类型的为null。
3)一维数组的静态初始化
在初始化的同时为数组元素赋值,例如
int [] score;
score=new int [] {89,80,30,79,40,99,66,88};
或
int [] score={89,80,30,79,40,99,66,88};
在这种方法中,数组的长度是通过花括号中的元素个数来决定的。
4)一维数组的动态初始化
int[] a = new int[3];
for(int i=0;i<3;i++){
a[i] = i+1;}
或
int[] intArray;//声明数组
intArray = new int[5];//为数组分配空间
所谓的静态和动态是相对于程序运行是而言的,
静态是在程序编译时就初始化好了的,
动态初始化是在程序运行是才动态分配内存空间。
对于代码而言,其实都可以。
唯一不一样的地方, 就是动态的初始值都是0,静态的是直接给定值了。
5)一维数组的引用
数组名[数组下标];
数组下标:它的值必须是在0和length-1之间。
引用数组时需要注意以下几点:
数组的下标是从0开始的。
引用数组元素时,如果下标越界,则将出现运行时异常。
6)一维数组的遍历
可以使用for循环和java5.0中新增的增强型for循环实现对数组的遍历。
(1)for循环
(2)增强型for循环
使用增强型for循环时要注意:循环变量必须在for表达式中声明,如for(int x : score)中的整型变量int x。
增强型for循环的最大优点是不需关心数组的下标,从而从根本上消除了“下标越界”这个可能的安全隐患。因此,建议在数组遍历时尽可能使用增强型for循环。
7)一维数组的内存分配
在java中,基本数据类型变量的数据是直接保存在栈(Stack)中的,引用数据类型变量在栈中保存了一个指针,而将实际数据保存在堆(Heap)中,栈中的指针指向堆中的数据。
当声明一个一维数组时,在栈中生成一个与该数组名相同的引用变量(指针)。例如int [] a; 在栈中生成一个名为a的引用变量,这时还未生成任何实际的数组,所以在堆中没有任何相应的信息。然后用new关键字创建数组如下:a =new int[3]; 这时,new关键字生成了一个数组,这个数组是在堆中的,共有3个元素。引用变量的指针指向这个数组。直到这时,数组才是可以被访问的。一旦这个数组不再被需要时,java将自动释放它所占用的内存。
(2)二维数组
1)二维数组的声明
声明二维数组的方法有以下3种。这3种方法是等价的,但一般使用第3种方法。
数据类型 数组名 [][];
数据类型 [] 数组名 [];
数据类型 [][] 数组名;
声明二维数组时需要注意以下几点。
- 二维数组的最后一维的所有元素具有相同的数据类型。
- 二维数组的非最后一维的所有元素时数组类型。
- 声明二维数组时,同样不能在方括号中指定数组的长度,int[3][40] score;
- 声明数组而没有对其初始化就直接使用,将会出现编译错误。
2)二维数组的创建(初始化)
二维数组也必须初始化后才能使用。有两种初始化的方法。
(1)直接为每一维分配空间
在分配内存空间的同时,同时设置第一维和第二位的大小。
数组名=new 数据类型[第一维的长度][第二维的长度];
使用时需要注意以下几点:
- 数据类型:必须与数组变量的数据类型相同。
- 数组每一维的大小一旦设置,即分配了内存空间,其大小就再也不能改变了。
- 数组每一维的大小确定以后,其长度值被保存在数组的length属性中,该属性时final的、不可改变的。
- 分配空间的同时,将为每一个元素设置初始化为为默认值。
(2)从高维开始,分别为每一维分配空间
使用第一种方法初始化的二维数组是一个规则的数组,使用此种方法实现不规则数组的初始化。
数组名 = new 数据类型[第一维的长度][];
数组名[0]=new 数据类型[第二维中第1行的长度];
数组名[1]=new 数据类型[第二维中第2行的长度];
数组名[2]=new 数据类型[第二维中第3行的长度];
……
使用时注意以下几点:
数组名 = new 数据类型 [] [第二维的长度]; //错误的
- 必须为第二维的每个数组分配内存空间,否则没被分配空间的元素时不可访问的。
3)二维数组的静态初始化
int [] [] a;
a=new int [] [] {{1},{2,3},{4,5,6}};
或
int [] [] a={{1},{2,3},{4,5,6}};
4)二维数组的引用
数组名[ 下标1 ][ 下标2 ];
5)二维数组的遍历
(1)for循环
(2)增强型for循环
6)二维数组的内存分配
当声明一个二维数组时,在栈中生成一个与该数组名相同的引用变量(指针)。例如int [] [] a; 在栈中生成一个名为a的引用变量,这时还未生成任何实际的数组,所以在堆中没有任何相应的信息。然后用new关键字创建数组(从高维开始):a =new int[3] [] ; 这时,new关键字生成了一个数组,这个数组是在堆中的,共有3个元素,而这3个元素时数组。还需要分别为它们分配空间:a[0] =new int[1]; a[1]=new int[2]; a[2]=new int [3]; 直到这时,数组才是可以被访问的。一旦这个数组不再被需要时,java将自动释放它所占用的内存。