epee_no_front's Notes
Happy learning! Happy Coding!
Toggle navigation
epee_no_front's Notes
主页
codeforces
人工智能
JAVA
python
Latex&Markdown
计算机系统
关于我
归档
标签
ch01 Java语言基础
java
2020-06-07 12:19:21
308
0
0
admin
java
# ch01 Java语言基础 参考: 孙卫琴 Java面向对象编程 第2版 唐大仕 Java程序设计 第2版 Java语言程序设计 基础篇 第10版 [TOC] ## 1 数据类型和变量 ![Java数据类型](https://picture-bed-bucket.oss-cn-beijing.aliyuncs.com/img/20200405194520.png) ### 1.1 基本数据类型 基本数据类型的取值范围 ![基本数据类型的取值范围](https://picture-bed-bucket.oss-cn-beijing.aliyuncs.com/img/20200405194755.png) #### 1.1.1 bool类型 注意:默认初始值为false。 Java虚拟机对boolean类型的处理比较特别。当Java编译器把Java源代码编译为字节码时,会用int 或byte来表示boolean。在Java虚拟机中,用整数零来表示false,用任意一个非零整数来表示true。当然,Java 虚拟机这种底层处理方式对Java源程序是透明的。**在Java源程序中,不允许把整数或null赋值给boolean类型的变量**,这是有别于其他高级语言(如C语言)的地方。因此以下代码是不合法的: ```java boolean a = 0; boolean b = null; ``` #### 1.1.2 byte、short、int和long类型 ##### 1 选择合适的整数类型 在Java 语言中,如果数学表达式中都是整数,那么表达式的返回值只可能是int类型或long类型,**如果把返回值赋给byte类型的变量,就必须进行强制类型的转换**,例如: ```java byte a = 1; a = a + 2; ///编译错误,a+2的结果为int类型 a = (byte)(a + 2); //合法 ``` ##### 2 给整数类型变量赋值 如果一个整数值在某种整数类型的取值范围内,就可以把它直接赋值给这种类型的变量,否则必须进行强制类型的转换。 ```java byte b = (byte) 129; // b的取值为-127 ``` 以上代码中的“(byte)”表示把129强制转换为byte类型。byte 类型的数据在内存中只占一个字节(8位),而129的二进制形式为: 0000000 00000000 00000000 10000001。“(byte)”运算符对129进行强制类型转换,它**截取**后8位,把它赋值给变量b, 因此变量b的二进制取值为0000001,它是一个负数,对应的十进制取值为-127。 如果在一个整数后面加上后缀:大写“L”或小写“l”,就表示它是一个long型整数,以下两种赋值方式是等价的: ```java long var = 100L; long var = 100l; ``` Java语言允许把二进制(以“0b”开头)、八进制(以“0”开头)、十六进制(以“0x”开头)和十进制数赋值给整数类型变量,例如: ```java int a0=0b110; //0b110为二进制数,变量a0的十进制取值为6 int al = 012; //012为八进制数,变量al的十进制取值为10 int a2=0x12; //0x12为十六进制数,变量a2的十进制取值为18 int a3=12; //12为十进制数,变量a3的十进制取值为12 int a4=0xF1; //0xF1为十六进制数,变量a4的十进制取值为241 byte b=(byte)0xF1; /0xF1 为十六进制数,变量b的十进制取值为-15 ``` **特别注意:012是八进制数的12,十进制下值为10。** ##### 3 用符号 "_" 分割数字,提高可读性 ```java int a = 10_000_000; //等价于 int a = 10000000; ``` #### 1.1.3 char类型与字符编码 Java对字符采用Unicode编码。 >Unicode编码由国际Unicode协会编制,收录了全世界所有语言文字中的字符,是一种跨平台的字符编码。UCS (Universal Character Set) 是指采用Unicode编码的通用字符集。 >Unicode具有两种编码方案: >用两个字节 (16位)编码,采用这个编码方案的字符集称为UCS-2. Java语言采用的就是两个字节的编码方案。 >用4个字节(32位)编码(实际上只用了31位,最高位必须为0),采用这个编码方案的字符集被称为UCS-4。 Java语言使用转义字符来表示单引号和其他特殊字符。 ```java char c1 = '\''; System.out.println(c1); // 打印一个单引号 char c2 = '\\; System.out.println(c2); // 打印一个反斜杠 char c3 = '\"'; System.out.println(c3); // 打印一个单双引号 ``` 常用转义字符 | 转义字符 | 描述 | |--------|--------| | \n | 换行符,将光标定位在下一行的开头 | | \t | 垂直制表符,将光标移到下一个制表符的位置 | | \r | 回车,将光标定位在当前行的开头;不会跳到下一行 | | \\\\ | 代表反斜杠字符 | | \\' | 代表单引号字符 | | \\" | 代表双引号字符 | #### 1.1.4 float 和 double 类型 Java语言支持两种浮点类型的小数: float:占4个字节,共32位,称为单精度浮点数。 double:占8个字节,共64位,称为双精度浮点数。 ### 1.2 引用类型 $$ 引用类型 \begin{cases} 类引用类型\\ 接口引用类型\\ 数组引用类型 \end{cases} $$ #### 1.2.1 基本类型和引用类型的区别 #### 1.2.2 用 new 关键字创建对象 $$ new的作用: \begin{cases} 为对象分配内存空间,将对象的实例变量自动初始化为其变量类型的默认值\\ 如果实例变量在声明时被显式初始化,那就把初始化值赋给实例变量\\ 调用构造方法\\ 返回对象的引用\\ \end{cases}$$ 一个对象可以被多个引用变量引用: ```java Doll doll1 = new Doll("贝贝"); Doll doll2 = new Doll("晶晶"); Doll doll3 = doll1; Doll doll4 = null; ``` ![Doll实例与引用变量的关系](https://picture-bed-bucket.oss-cn-beijing.aliyuncs.com/img/20200405214357.png) ### 1.3 变量的作用域 按照作用域的不同,变量可分为以下类型: **成员变量**:在类中声明,它的作用域是整个类。 **局部变量**:在一个方法的内部或方法的一个代码块的内部声明。如果在一个方法内部声明,它的作用域是整个方法;如果在一个方法的某个代码块的内部声明,那么它的作用域是这个代码块。代码块是指位于一对大括号{}以内的代码。 **方法参数**:方法或者构造方法的参数,它的作用域是整个方法或者构造方法。 **异常处理参数**:异常处理参数和方法参数很相似,差别在于前者传递参数给异常处理代码块,而后者传递参数给方法或者构造方法。异常处理参数是指catch(Exception e)语句中的异常参数“e”,它的作用域是紧跟着catch(Exception e)语句后的代码块。 #### 1.3.1 实例变量和静态变量的生命周期 $$ 类的成员变量有两种 \begin{cases} 一种是被static关键字修饰的变量,叫类变量,或静态变量;\\ 一种是没有被static关键字修饰的变量,叫实例变量。\\ \end{cases}$$ 静态变量和实例变量的区别在于: * 类的静态变量在内存中只有一个,Java 虚拟机在加载类的过程中为静态变量分配内存,静态变量位于方法区,被类的所有实例共享。静态变量可以直接通过类名被访问。静态变量的生命周期取决于类的生命周期,当加载类的时候,静态变量被创建并分配内存,当卸载类的时候,静态变量被销毁并撤销内存。 * 类的每个实例都有相应的实例变量。每创建一个类的实例,Java 虚拟机就会为实例变量分配一次内存, 实例变量位于堆区中。实例变量的生命周期取决于实例的生命周期,当创建实例的时候,实例变量被创建并分配内存,当销毁实例的时候,实例变量被销毁并撒销内存。 #### 1.3.2 局部变量的生命周期 局部变量的生命周期取决于所属的方法何时被调用及结束调用。 * 当Java虚拟机(更确切地说,是Java虚拟机中的某个线程)调用一个方法时,会为这个方法中的局部变量分配内存。 * 当Java虚拟机(更确切地说,是Java虚拟机中的某个线程)结束调用一个方法时,会结束这个方法中局部变量的生命周期。 由于局部变量和成员变量有着完全不同的生命周期,在使用局部变量时,受到以下限制: * 局部变量不能被 $static$ 、 $private$ 、 $protected$ 和 $public$ 等修饰符修饰。 * 不能通过类名或引用变量名来访问局部变量。 #### 1.3.3 成员变量和局部变量同名 在同一个作用域内不允许定义同名的多个变量。 在一个方法内,可以定义和成员变量同名的局部变量或参数,此时成员变量被屏蔽。此时如果要访问实例变量,可以通过 $this$ 关键字来访问, $this$ 为当前实例的引用。 如果要访问类变量,可以通过类名来访问。 #### 1.3.4 将局部变量的作用域最小化 为了将局部变量的作用域最小化,应该遵守以下规则: * 在需要使用某局部变量的时候,才定义它。对于以上例子,只需在if代码块中定义 var变量。 * 使方法小而集中。如果一个方法包含多种操作,尽可能把这个方法分解为多个小方法,每个方法负责一项操作。这些小方法在Java源文件中可集中放在一起。方法变小了,局部变量的作用域也就自然变小了。 ### 1.4 对象的默认引用: **this** 在程序中,在以下情况会使用this关键字: 1 在类的构造方法中,通过this语句调用这个类的另一个构造方法(重载构造方法)。 2 在一个实例方法内,局部变量或参数和实例变量同名,实例变量被屏蔽,因此采用this.***的方式来指代实例变量。 3 在一个实例方法内,访问当前实例的引用。 值得注意的是,只能在构造方法或实例方法内使用 this 关键字,而在静态方法和静态代码块内不能使用this 关键字。 ### 3.5 参数传递 如果方法A调用方法B,那么称方法A是方法B的调用者。 **如果方法B的参数是基本数据类型,那么方法A向方法B传递参数的值。** **如果方法B的参数是对象或数组,那么方法A向方法B传递对象或数组的引用。** ```java public class ParamTester{ public int memberVariable=0; public static void main(String args[]){ //声明并初始化4个局部变量 int param1=0; // param1是基本数据类型 ParamTester param2=new ParamTester(); //param2 是对象引用类型 ParamTester param3=new ParamTester();//param3 是对象引用类型 int[] param4={0}; //param4是数组引用类型 //将4个局部变量作为参数传递给changeParameter()方法 changeParameter(param1, param2, param3, param4); //打印4个局部变量 System.out.println("param1=" +param1); System.out.println("param2.memberVariable="+param2.memberVariable); System.out.println("param3.memberVariable=" + param3.memberVariable); System.out.println("param4[0]="+param4[0]); } public static void changeParameter(int param1, ParamTester param2, ParamTester param3, int[] param4){ param1=1; //改变基本数据类型参数的值 param2.memberVariable=1; //改变对象类型参数的实例变量 param3=new ParamTester(); //改变对象类型参数的引用,使它引用一个新的对象 param3.memberVariable=1; //改变新的对象的实例变量 param4[0]=1; //改变数组类型参数的元素 } } ``` 输出结果为: ```output parameterl=0 parameter2.memberVariable=1 parameter3.memberVariable=0 parameter4[0]=1 ``` (尤其注意**parameter3**的情况!) ![主线程开始准备执行changeParameter()方法时方法调用栈的状态](https://picture-bed-bucket.oss-cn-beijing.aliyuncs.com/img/20200406141255.png) ![主线程执行changeParameter()方法完毕,即将退出该方法时方法调用栈的状态](https://picture-bed-bucket.oss-cn-beijing.aliyuncs.com/img/20200406141313.png) ### 1.6 变量的初始化以及默认值 Java语言要求变量遵循先定义、再初始化、再使用的规则。变量的初始化是指自从定义变量以后,首次给它赋初始值的过程。 #### 1.6.1 成员变量的初始化 对于类的成员变量,不管程序有没有显式地进行初始化,Java虚拟机会先自动给它初始化为默认值。初始化为默认值的规则为: >整数型(byte、 short、int 和long)的基本类型变量的默认值为0。 >单精度浮点型(float) 的基本类型变量的默认值为0.0f。 >双精度浮点型(double)的基本类型变量的默认值为0.0d。 >字符型(char)的基本类型变量的默认值为“\u0000”。 >布尔型的基本类型变量的默认值为false。 >引用类型的变量的默认值为null。 >数组引用类型的变量的默认值为null。 创建了数组变量的实例后,如果没有显式地为每个元素赋值,那么Java把该数组的所有元素初始化为其相应类型的默认值。 #### 1.6.2 局部变量的初始化 局部变量声明之后,Java 虚拟机不会自动给它初始化为默认值。因此对于局部变量,必须先显式初始化,才能使用它。如果编译器确认一个局部变量在使用之前可能没有被初始化,编译器将报错。 如果局部变量没有被初始化,并且在方法中一.直没有被使用,编译和运行都会通过。 ### 1.7 直接数 #### 1.7.1 直接数的类型 直接数是指直接赋给变量的具体数值。共7种类型的直接数:int型直接数, long型直接数, float型直接数, double型直接数, boolean型直接数, char型直接数, String型直接数。 Java直接数的类型具有如下特点: * 对于基本类型的数据,除了byte和short类型之外,都有相应的直接数。 * 对于整数,如123和2147483648,如果在int类型的取值范围内,就是int型直接数;否则,如果在long类型的取值范围内,就是long型直接数。对于long、float和double型直接数,可以分别加上后缀: L或l、F或f,以及D或d。 * 在整数后面加上“L”表示long型直接数,但不能以此类推:在整数后面加上“S”表示short型直接数,在整数后面加上“C”表示char型直接数。因此3S或者3C都是非法的直接数。 * **如果一个小数没有任何后缀,那么它是double型直接数**,例如1.0就是一个double类型的直接数。用十进制科学计数法表示的数字都是double型直接数,例如10E1和5E23都是double型直接数。 * **对于引用类型,只有String引用类型有直接数。** * String类型直接数和char类型的直接数的区别在于,前者表示字符串,位于双引号内,如"Hello",后者表示单个字符,位于单引号内,如‘H’。 #### 1.7.2 直接数的赋值 “ $\checkmark$ ”表示可以直接赋值。 “ $\times$ ”表示不允许赋值。 “cast”表示必须通过强制类型的转换。 “部分cast” 表示一部分直接数可以直接赋值,但是一部分直接数必须经过强制类型的转换。 ![直接数赋值给各种变量类型的规律 ](https://picture-bed-bucket.oss-cn-beijing.aliyuncs.com/img/20200406163046.png) ## 2 操作符 ### 2.1 操作符简介 常用操作符的优先级顺序: ![常用操作符的优先级顺序](https://picture-bed-bucket.oss-cn-beijing.aliyuncs.com/img/20200406172145.png) 多数操作符的结合性为从左到右,只有赋值操作符“=”,以及复合赋值操作符(如“+=”、“-=”和“*=”等)的结合性是从右到左的。 ```java int a, b; b = (a = 8 / 2 / 3) + 1; // 变量b的取值为2 ``` ### 2.2 整型操作符 在计算表达式时,**如果有一个操作元是long型,那么结果也是long型;否则不管操作元是byte、short 或char型,运算结果都是int型**。 #### 2.2.1 一元整型操作符 一元整型操作符表 ![一元整型操作符表](https://picture-bed-bucket.oss-cn-beijing.aliyuncs.com/img/20200406173603.png) #### 2.2.2 二元整型操作符 二元整型操作符表 ![二元整型操作符表](https://picture-bed-bucket.oss-cn-beijing.aliyuncs.com/img/20200406174143.png) 如果把一个整数除以0或者对0取模,程序就会在运行时抛出ArithmeticException运行时异常。 ### 2.3 浮点型操作符 同整型操作符相似,运算结果的类型和操作元中取值范围最大的类型一致。如果操作元中最大长度类型是 float 型,那么结果为 float 型。如果操作元中有一个或几个是 double 型,那么结果就是 double 型。 浮点运算不支持位运算。 Java浮点类型数据有两个特殊的值:负无穷大(-Infinity) 和正无穷大(Infinity)。它们可用来表示无效的浮点运算的结果。正数除以0得正无穷大,负数除以0得负无穷大。对于以下代码: ```java System.out.printhn(1.0/0.0); System.out.printn(- 1.0/0.0); ``` 打印如下结果: ```output Infinity -Infinity ``` ### 2.4 比较操作符和逻辑操作符 ![比较操作符和逻辑操作符](https://picture-bed-bucket.oss-cn-beijing.aliyuncs.com/img/20200406175053.png) “<”“>”“<=”和“>=”操作符的操作元只能是整数类型和浮点数类型。 “\==” 和 “!=”操作符的操作元既可以是基本类型,也可以是引用类型。 “&&”和“&”均为与操作符,操作元只能是布尔表达式,布尔表达式是指运算 结果为boolean类型的表达式。例如以下“&”操作符的两个操作元分别为布尔表达式 “a==b”和“a>1": ```java int a=2,b=2; boolean result = (a == b) & (a > 1); //result 的值为true ``` 下表为“&”操作符的运算规则。 ![“&”操作符的运算规则](https://picture-bed-bucket.oss-cn-beijing.aliyuncs.com/img/20200406175312.png) “||”和“|”均为或操作符,操作元也只能是布尔表达式,下表为“|”操作符的运算规则。 ![“|”操作符的运算规则](https://picture-bed-bucket.oss-cn-beijing.aliyuncs.com/img/20200406175342.png) **“&&”和“||”是短路(short circuit)操作符,“&”和“|”是非短路操作符,它们的区别是:对于短路操作符,如果能根据操作符左边的布尔表达式就能推算出整个表达式的布尔值,将不执行操作符右边的布尔表达式。对于非短路操作符,始终会执行操作符两边的布尔表达式。** ### 2.5 特殊操作符 "?:" Java语言中有一个特殊的三元操作符“?:”, 它的语法形式为: ```java 布尔表达式 ? 表达式1 : 表达式2; ``` 操作符“?:”的运算过程为:如果布尔表达式的值为true,就返回表达式1的值,否则返回表达式2的值。 ### 2.6 字符串连接操作符 "+" 操作符 "+" 能够连接字符串,并生成新的字符串。 如果 "+" 操作符中有一个操作元为 String 类型,则另一个操作元可以是任意类型(包括基本类型和引用类型),另一个操作元将被转换成字符串,**如果另一个操作元为引用类型,就调用所引用对象的 toString() 方法来获得字符串**。 Tips:在java.lang.Object类中定义了toString()方法,因此所有的Java类都有这一方法。 对于包含多个 "+" 操作符的表达式,Java 根据 "+" 的左结合性特点,从左边开始计算表达式。根据操作元的类型来决定 "+" 是字符串连接操作符,还是数学加法操作符。 ### 4.7 操作符 "==" 与对象的 equals() 方法 操作符“==”比较两个操作元是否相等,这两个操作元既可以是基本类型,也可以是引用类型。在java.lang.Object类中定义了equals(方法,用来比较两个对象是否相等。 #### 4.7.1 操作符 "==" 当操作符 "==" 两边都是引用类型变量时,这两个引用变量必须都引用同一个对象,结果才为true。 ##### 1 操作符 "==" 与多态性 "\==" 用于比较引用类型变量时,"\==" 两边的变量被显式声明的类型必须是同种类型或有继承关系,即位于继承树的同一个继承分支上,否则编译报错。而在运行时,Java 虚拟机将根据两边的引用变量实际引用的对象进行比较。 例如: 假设有4个类Creature、Animal、Dog和Cat类,它们的继承关系如下图所示。 ![继承关系](https://picture-bed-bucket.oss-cn-beijing.aliyuncs.com/img/20200406193010.png) 以下代码中变量dog被声明为Dog类型,变量animal被声明为Animal类型,它们之间有继承关系,尽管这两个变量实际上引用的Dog对象和Cat对象之间没有继承关系,仍然可以用 "\==" 表达式比较: ```java Dog dog = new Dog(); //dog变量被声明为Dog类型 Creature creature = dog; //变量creature和dog引用同一个Dog对象 Animal animal = new Cat(); //animal变量被声明为Animal类型 System.out.println(dog==animal); //合法,打印false System.out.println(dog==creature); //合法,打印true ``` 以下代码中变量dog被声明为Dog类型,变量cat被声明为Cat类型,Dog类和Cat类之间没有继承关系,因此这两个引用变量不能用 "==" 比较: ```java Dog dog = new Dog(); Cat cat = new Cat(); System.out.println(dog == cat); //编译出错 ``` ##### 2 操作符 "==" 用于数组类型 数组类型也是引用类型,也可以用 "==" 进行比较。 ```java boolean b1 == new int[4] == new long[5]; //编译出错, 两边类型不一致 boolean b2 == new int[4] == new int[4]; //合法,b2的值为false int[] array1 = new int[4]; int[] array2 = array1; boolean b3 = array1 == array2; //合法,b3的值为true ``` #### 4.7.2 对象的 equals() 方法 equals()方法是在Object类中定义的方法,它的声明格式如下: ```java public boolean equals(Object obj) ``` Object类的equals()方法的比较规则为:当参数obj引用的对象与当前对象为同一个对象时,就返回true,否则返回false: ```java public boolean equals(Object obj){ if(this == obj) return true; else return false; ``` 在 JDK 中有一些类覆盖了 Object 类的 equals() 方法,它们的比较规则为:如果两个对象的类型一致,并且内容一致,则返回true。这些类包括:java.io.File、java.til.Date、java.lang.String、包装类(如java.lang.Integer和java.lang.Double类)。 在实际运用中,**比较字符串是否相等时**,通常都是按照内容来比较才会有意义,因此应该**调用 String 类的 equals() 方法**,而不是采用 "\==" 操作符。 在用户自定义的类中也可以覆盖 Object 类的 equals() 方法,重新定义比较规则。 ### 2.8 instanceof 操作符 instanceof 操作符用于判断一个引用类型所引用的对象是否是一个类的实例。instanceof 操作符左边的操作元是一个引用类型,右边的操作元是一个类名或接口名。形式如下: ```java obj instanceof ClassName 或者 obj instanceof InterfaceName ``` 一个类的实例包括类本身的实例,以及所有直接或间接的子类的实例。 #### 1 instanceof 与多态性 instanceof 左边操作元被显式声明的类型和右边操作元必须是同种类或有继承关系,即位于继承树的同一个继承分支上,否则编译出错。 在运行时,将**根据左边操作元实际引用的对象来判断**,例如: ```java Animal animal=new Dog0; //animal 变量被声明为Animal类型,引用Dog对象 System.out.println(animal instanceof Animal); //合法, 打印true System.out.println(animal instanceof Dog);//合法,打印true System.out.println(animal instanceof Cat); //合法,打印false ``` #### 2 instanceof 用于数组类型 数组类型也可以用 instanceof 进行比较。 ```java boolean b1 = new int[4] instanceof long[]; //编译出错,instanceof 两边操作元的类型不一致 boolean b2 = new int[4] instanceof int[]; //合法,b2的值为true ``` ### 2.9 变量的赋值和类型转换 #### 2.9.1 基本数据类型转换 整型、浮点型、字符型数据可以进行混合运算。当类型不一致时,需要进行类型转换,从低位类型到高位类型会进行自动转换,而从高位类型到低位类型需要进行强制类型的转换。值得注意的是 boolean 类型不能与其他的基本类型进行类型转换。 ##### 1 自动类型转换 表达式中操作元自动转换的规则: * (byte、char、 short、 int、 long 或float) op double $\rightarrow$ double * (byte、char、 short、 int 或 long) op float $\rightarrow$ float * (byte、char、 short 或 int) op long $\rightarrow$ long * (byte、char 或 short) op int $\rightarrow$ int * (byte、char 或 short) op (byte、char 或 short) $\rightarrow$ int 箭头左边表示参与运算的数据类型,op为操作符(如加"+"、减"-"、乘"*"和除"/"等),箭头右边表示自动转换成的数据类型。以上转换规则表明: * 当表达式中存在double类型的操作元时,那么把所有操作元自动转换为double类型,表达式的值为double类型。 * 否则,当表达式中存在float 类型的操作元时,那么把所有操作元自动转换为float类型,表达式的值为float类型。 * 否则,当表达式中存在long类型的操作元时,那么把所有操作元自动转换为long类型,表达式的值为long类型。 * 否则,把所有操作元自动转换为int类型,表达式的值为int类型。 Tips: byte、short和char类型的数据在如x++这样的一元运算中不自动转换类型。 注: ```java int x = 6; double d= 7.7; System.out.println((x > d) ? 99.9 : 9); //打印9.0 ``` 在进行赋值运算时,也会进行低位到高位的自动类型转换,赋值运算的自动类型转换规则如下: byte $\rightarrow$ short $\rightarrow$ int $\rightarrow$ long $\rightarrow$ float $\rightarrow$ double byte $\rightarrow$ char $\rightarrow$ int $\rightarrow$ long $\rightarrow$ float $\rightarrow$ double 在给方法传递参数时,也会出现类型自动转换的情况,转换规则与赋值运算的自动转换规则相同。 ##### 2 强制类型转换 如果把高位类型赋值给低位类型,必须进行强制类型转换,否则,编译会出错。 在给方法传递参数时,如果把高位类型传给低位类型,也需要强制类型转换。 #### 2.9.2 引用类型的类型转换 引用类型的变量之间赋值时,**子类赋值给直接或间接父类,会自动进行类型转换。父类赋值给直接或间接子类,需要进行强制类型转换。** 对于引用类型变量,Java 编译器只根据变量被显式声明的类型去编译。引用类型变量之间赋值时,“=”操作符两边的变量被显式声明的类型必须是同种类型或有继承关系,即位于继承树的同一个继承分支上,否则编译报错。 ## 3 流程控制 ### 3.1 分支语句 ```math Java 支持两种分支语句 \begin{cases} if else 语句\\ switch 语句\\ \end{cases} ``` #### 3.1.1 if else 语句 注意事项: * **if后面的表达式必须是布尔表达式,而不能为数字类型**,这一点与C/C++语言不同。 * if语句后面的else语句并不是必需的。 * (3)假如if语句或else语句的程序代码块中包括多条语句,则必须放在大括号{}内;如果程序代码块只有一条语句,可以不用大括号{}。流程控制语句(如if else语句、for 语句、while语句和switch语句等)可作为一条语句看待。 #### 3.1.2 switch 语句 ```java switch(expr) { case valuel statements; break; ... case valueN statements; break; default: statements; break; } ``` 注意事项: (1) 在switch(expr) 语句中,expr表达式的类型包括以下几种: * 与 int 类型兼容的基本类型,所谓与 int 类型兼容,就是指能自动转换为 int 类型。因此 expr 表达式的合法类型包括: byte、short、char 和 int 类型。long 和浮点类型不能自动转换为 int 类型,因此不能作为 expr 表达式的类型。 * 字符串类型。例如以下switch语句中的colour变量为字符串类型。 * 枚举类型。 (2) 在 "case valueN" 子句中,valueN 表达式必须满足以下条件: * valueN 的类型必须是与 int 类型兼容的基本类型,包括: byte、short、char 和 int类型。或者是字符串类型和枚举类型。 * valueN必须是常量。 * 各个case子句的valueN表达式的值不同。 (3) 在 switch 语句中最多只能有一个 default 子句。default子句是可选的。当 switch 表达式的值不与任何 case 子句匹配时,程序执行 default 子句,假如没有 default 子句,则程序直接退出 switch 语句。default 子句可以位于 switch 语句中的任何位置,通常都将 default 子句放在所有 case 子句的后面。 (4) 如果 switch 表达式与某个 case 表达式匹配,或者与 default 情况匹配,就从这个 case 子句或 default 子句开始执行,假如遇到 break 语句,就退出整个switch语句,否则依次执行 switch 语句中后续的 case 子句,不再检查 case 表达式的值。 ### 3.2 循环语句 循环语句包含四部分内容: * 初始化部分:用来设置循环的一些初始条件,比如设置循环控制变量的初始值。 * 循环条件:这是一个布尔表达式。每一次循环都要对该表达式求值,以判断到底是继续循环还是终止循环。这个布尔表达式中通常会包含循环控制变量。 * 循环体:这是循环操作的主体内容,可以是一条语句,也可以是多条语句。 * 迭代部分:通常属于循环体的一部分,用来改变循环控制变量的值,从而改变循环条件表达式的布尔值。 ```math java提供三种循环语句 \begin{cases} for语句\\ while语句\\ do while语句\\ \end{cases} ``` #### 3.2.1 while 语句 ```java [初始化部分] while(循环条件){ 循环体,包括迭代部分 } ``` #### 3.2.2 do while 语句 ```java [初始化部分] do { 循环体,包括迭代部分 }while(循环条件); ``` #### 3.2.3 for 语句 ```java for(初始化部分; 循环条件; 迭代部分){ 循环体 } ``` #### 3.2.4 foreach 语句 foreach语句是for语句的特殊简化版本,它可以简化遍历数组和集合的程序代码。foreach语句的语法格式如下: ```java for(元素类型 元素变量x: 待遍历的集合或数组){ 引用了变量x的java语句; } ``` #### 3.2.5 多重循环 ### 3.3 流程跳转语句 ```math \begin{cases} break:\\ \ \ \ \ \ 从switch语句、循环语句或标号标识的代码块中退出。\\ continue\\ \ \ \ \ \ 跳过本次循环,执行下一-次循环,或执行标号标识的循环体。\\ return\\ \ \ \ \ \ 退出本方法,跳到上层调用方法;如果本方法的返回类型不是void,需要提供相应的返回值。\\ \end{cases} ``` **break语句和continue语句可以与标号联合使用**。标号用来标识程序中的语句,标号的名字可以是任意的合法标识符。例如在以下代码中,“loopl”和“loop2”为标号,分别标识for语句和switch语句: ```java loopl: for(int i = 0; i < 5; i++){ loop2: switch(i){ case 0: Systerm.out.println("0"); break; //退出switch语句 case 1: System.out.println("1"); break loop2; //退出switch语句 case 3: System.out.printhln("3"); break loop1; //退出for循环 default: System.out.println("default"); continue loopl; /结束本次for循环,执行下次for循环 System.out.println("i="+i); } } ``` 以上程序的打印结果为: ```output 0 i=0 i=1 1 default 3 ``` 在使用标号时,有以下注意事项: (1) 在语法上,标号可用来标识除变量声明语句之外的任何有效语句。 (2) continue 语句中的标号必须定义在 while、do while 和 for 循环语句前面。 (3) break 语句中的标号必须定义在while、do while 和for循环语句或switch语句前面。
上一篇:
人工智能基础课程实践结果呈现
下一篇:
数论模板
0
赞
308 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
提交评论
立即登录
, 发表评论.
没有帐号?
立即注册
0
条评论
More...
皖ICP备20006612号
皖公网安备 34020302000165号
文档导航
没有帐号? 立即注册