您的位置:首页 > 职场人生

黑马程序员-Java基础知识预备之Java流程控制与数组

2013-07-09 08:45 645 查看
-------- android培训java培训、期待与您交流!----------

本博文涉及的主要内容如下:
if语句
switch语句
循环结构
循环结构的控制
数组类型
数组在内存中的运行机制
基本类型数组的初始化过程
引用类型数组的初始化过程

一、if语句
有以下三种格式:

第一种格式:
if(logic expression)//logic[ˈlɑdʒɪk]:逻辑    expression[ɪkˈsprɛʃən]表达式
{
statement...//statement[ ˈstetmənt]表现
}
第二种格式:
if(logic expression)
{
statement...
}
else
{
statement...
}
第三种格式:
if(logic expression_1)
{
statement1...
}
else if(logic expression_2)
{
statement2...
}
...//可能有多个else if语句
else//最后的else语句可以省略
{
statement3...
}
如果if、else if、和else后的代码块只有一行语句时,则可以省略花括号,因为单行语句本身就是一个整体。但建议不要省略其后的花括号,即使条件执行体只有一行代码。这样会有更好的可读性,而且会减少发生错误的可能。

二、switch语句
switch语句由一个控制表达式和多个case标签组成,和if语句不同的是,switch语句后面的控制表达式的数据类型只能是byte、short、char、int四个整数类型和枚举类型,不能是boolean类型。

Java 7改进了switch分支语句,充许switch语句中的控制表达式为java.lang.String类型。

格式如下:
switch (expression)
{
case condition1:
{
statement(s)
break;
}
case condition2:
{
statement(s)
break;
}
...
case conditionN:
{
statement(s)
break;
}
default:
{
statement(s)
}
}
小结:
需要注意的地方:
case之间与default没有顺序,先执行第一个case,没有匹配的case执行default。

结束switch语句的两种情况:遇到break;执行到switch语句结束。

如果匹配的case或者default没有对应的break,那么程序会继续向下执行,运行可以执行的语句,直到遇到break或者switch语句结束。

三、循环结构
1、while循环语句
格式如下:
[init_statement]//init_statement:初始化语句,充许多条。
while (expression)//expression:循环条件,是一个boolean表达式,决定是否执行循环体
{
statement;
[init_statement]
}
2、do while循环语句
格式如下:
[init_statement]//init_statement:初始化语句,充许多条。
do
{
statement;
[init_statement]
}while (expression)
3、for循环
格式如下:
for ([init_statement]; [expression]; [iteration_statement])
{
statement;
}
4、嵌套循环

一个例子来说明:
class ForNestedLoopTest
{
public static void main(String[] args)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
System.out.println("i="+i+"..."+"j"=j);
}
}
}
}


四、循环结构的控制
1、使用break结束循环
2、使用continue结束本次循环
3、使用return结束方法

五、数组类型
1、定义数组
Java语言支持两种语法格式来定义数组
type[] arrayName;//建议采用
type arrayName[];//不建议采用
2、数组的初始化
//静态初始化方式:初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组长度。
//格式1:
arrayName = new type[]{element1, element2, element3, ...};
//格式2(简化方式):
arrayName = {element1, element2, element3, ...};
//
//动态初始化方式:初始化时程序员只指定数组长度,由系统为数组元素分配初始值。
//数组的定义和初始化同时完成,使用动态初始化语法。
int[] a = new int[5];
//数组的定义和初始化同时完成,初始化数组时元素的类型是定义数组时元素类型的子类。
Object[] books = new String[4];
需要注意的是:
执行动态初始化时,程序员只需要指定数组的长度,即为每个数组元素指定所需要的内存空间,系统将负责为这些数组元素分配初始值。指定初始值时,系统按如下规则分配初始值。
数组元素的类型是基本类型中的整数类型(byte,short,int和long),则数组元素的值为0。

数组元素的类型是基本类型中的浮点类型(float,double),则数组元素的值为0.0。

数组元素的类型是基本类型中的字符类型(char),则数组元素的值为'\u0000'。

数组元素的类型是基本类型中的布尔类型(boolean),则数组元素的值为false。

数组元素的类型是引用接口类型(类、接口和数组),则数组元素的值为null。

六、数组在内存中的运行机制
数组是一种引用数据类型,数组引用变量只是一个引用,数组元素和数组变量在内存里是分开存放的。下面以一个例子来具体说明:
class ArrayInRam
{
public static void main(String[] args)
{
//定义并初始化数组,使用静态初始化
int[] a = {1, 2, 3};

//定义并初始化数组,使用动态初始化
int[] b = new int[4];
//输出b数组的长度
System.out.println("b数组长度为:"+b.length);
//遍历a数组中的元素
for(int i : a)
{
System.out.println(i);
}
//遍历b数组中的元素
for(int i : b)
{
System.out.println(i);
}
//因为a是int[]类型,b也是int[]类型,所以可以将a的值赋给b.
//实际上是让b引用指向了a引用指向的数组
b = a;
//再次输出b数组的长度
System.out.println("赋值后的b数组长度为:" + b.length);
}
}
/*
--------------------------
输出结果为:
b数组长度为:4
1
2
3
0
0
0
0
赋值后的b数组长度为:3
--------------------------
*/
运行上面代码后,将可以看到先输出b数组的长度为4,然后依次输出a数组和b数组的每个数组元素,接着会输出b数组的长度为3,这似乎有违数组长度是固定的规则,不过这只是一个假象,所以必须注意:定义并初始化一个数组后,在内存中分配了两个空间,一个用于存放数组的引用变量(堆heap),另一个用于存放数组本身(栈stack)。示意图如下:


当执行上面的b = a;代码时,系统会把a的值赋给b,a和b都是引用类型变量,存储的是地址,因此把a的值赋给b后,就是让b指向a所指向的地址。此时计算机内存的存储示意图如下:


七、基本类型数组的初始化过程 对于基本类型数组而言,数组元素的值直接存储在对应的数组元素中,因此,初始化数组时,先为该数组分配内在空间,然后直接将数组元素的值存入对应的数组元素中。
下面以一个例子来具体说明:
class ArrayTest1
{
public static void main(String args[])
{
//定义一个int[]类型的数组变量
int[] iArr;
//动态初始化数组,数组长度为5
iArr = new int[5];
//采用遍历的方式为每个数组赋值。
for(int i = 0; i < iArr.length; i++)
{
iArr = i + 1;
}
//打印输出语句省略
}
}
执行代码int[] iArr;时,仅定义一个数组变量,此时内存中的存储示意图如下: 此时仅在栈内存中定义了一个空引用 ,这个引用并指向任何有效的内存。


当执行代码iArr = new int[5];动态初始化后,系统将负责为该数组分配内存空间,并分配默认的初始值,即所有数组元素的值均为0,此时内存中的存储示意图如下:


当显示指定每个数组元素值后,此时内存中存储的示意图如下:


八、引用类型数组的初始化过程 引用类型数组的数组元素是引用,因此情况会复杂化,每个数组元素里存储的还是引用,它指向另一块内存,这块内存里存储了有效数据。
下面以一个例子详细说明:
class Person
{
//年龄
public int age;
//身高
public int height;
public void info()
{
System.out.println("年龄:"+age+",身高:"+height);
}
}
class ArrayTest2
{
public static void main(String[] args)
{
//定义一个students数组变量,其类型是Person[]
Person[] students;
//执行动态初始化
students = new Person[2];
//创建一个Person实例,并将这个Person实例赋给zhangsan变量
Person  zhangsan = new Person();
zhangsan.age = 23;
zhangsan.height = 167;
//为lisi所引用的Person对象的age、heigth赋值
lisi.age = 31;
lisi.height = 162;
//将zhangsan变量的值赋给第一个数组元素。
students[0] = zhangsan;
//将lisi变量的值赋给第二个数组元素。
student[1] = lisi;
//下面两行代码的结果完全一样,因为lisi和student[1]指向的是同一个Person实例
lisi.info();
students[1].info();
}
/*
--------------------
运行结果:
年龄:31,身高:162
年龄:31,身高:162
--------------------
*/
当执行Person[] students;代码时,这行代码仅仅在栈内存中定义了一个引用变量,也就是一个指针,不过这个指针没有指向任何有效的内存区。此时内存中存储示意图如下:


动态初始化students数组后,由系统为数组元素分配默认的初始值:null,即每个数组元素的值都是null。此时存储示意图如下:


创建两个Person对象后的存储示意图如下:


为数组元素赋值后的存储示意图如下:


此时zhang和students[0]指向同一个内存区,而且它们都是引用类型变量,因此通过zhangsan和students[0]来访问Person对象Field和方法的效果完全一样。

-------- android培训java培训、期待与您交流!----------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息