ch03 目标:表达式和流程控制 ---------------------------------------------- 1.实例变量和局部变量 程序的基本功能是处理数据,程序中需要使用变量来接收并表示数据。 程序中的变量必须先定义之后才能使用。 定义变量包括定义变量的"类型"以及变量的"名字"。 例如: int a; Student s; 程序中的变量分为实例变量和局部变量。 1)实例变量(又称属性、全局变量、成员变量) 位置: 直接定义在中类,属于类中的一种成员(成员变量/成员方法)。 例如: public class Student{ public String name; } 作用范围: 是指变量定义之后,都在哪些地方可以被访问到。 由于实例变量是直接定义在类中的,所以在定义的时候可以使用修饰符进行修饰。 例如:这四种修饰符的作用之后会介绍到 public class Student{ public String name1; protected String name2; String name3; private String name4; } 以上是使用了四种访问权限控制修饰符来修饰了这四个变量。 但是不管是哪种修饰符情况,实例变量再当前类中的每一个方法都是可以被访问到的(static修饰的静态方法除外)。 public class Student{ public String name1; protected String name2; String name3; private String name4; //类中的方法里面可以直接访问实例变量 public void run(){ System.out.println(name1); System.out.println(name2); System.out.println(name3); System.out.println(name4); } } 默认值: 类的中实例变量声明后,如果我们没有显式赋值的话,每种实例变量其实都是有自己的默认值的。 实例变量的赋值分为隐式赋值和显式赋值 隐式赋值就是JVM给它赋的值(就是说的默认值) 显式赋值就是我们主动给它赋的值 例如: public class Student{ public int a; public float f; public char c; public boolean b; public String str; public void println(){ System.out.println(a); System.out.println(f); System.out.println(c); System.out.println(b); System.out.println(str); } } 基本类型的实例变量: 整型 :默认值为 0 浮点型 :默认值为 0.0 布尔型 :默认值为 false 字符型 :默认值为 0 或者 '\u0000' 引用类型的实例变量: 默认值都是 null 生命周期: 实例变量是属于对象的,一个对象被创建出来的时候,这个对象中的实例变量就有了,直到这个对象被GC当做垃圾回收之后,这个实例变量也就没有了。 1)局部变量 位置: 定义在方法的代码块中或者方法的参数列表中 例如:a b c d四个都是局部变量 public void test(int a){ int b; { int c; } if(true){ int d; } } 作用范围: 1)如果是定义在方法的参数列表中,那么在当前方法的任何位置都可以访问该局部变量 例如: public void test(int a){ System.out.println(a); { System.out.println(a); } if(true){ System.out.println(a); } } 2)如果是定义在方法中,那么就要看这个局部变量是"直接"位于哪一对大口号内 例如: public void test(){ int a; { int b; } if(true){ int c; } } 观察局部变量a/b/c三个分别是"直接"位于哪一对大括号内,那么这个局部变量的作用范围就在那一对大括号内. 如果访问的地方出了这个范围,那么是访问不到这个局部变量的。 默认值: 局部变量是"没有"默认值的,我们只能显式的赋值之后才能使用该变量,否则会编译报错. 例如: //编译通过 //只定义了变量但是没有使用 public void test(){ int a; } //编译报错 //因为在使用局部变量之前没有赋值 public void test(){ int a; System.out.println("a = "+a); } //编译通过 //只有在使用之前赋值就可以了 //int a = 1; //当然声明的同时就赋值也是可以的 public void test(){ int a; a = 1; System.out.println("a = "+a); } 声明周期: 当方法被调用,代码执行到局部变量的声明这一刻开始,这个局部变量就出现了,直到局部变量"直接"位于的大括号内中的代码执行结束的时候,该变量在内存中也就释放消失了。 例如: //test方法执行完,变量a就没有了 public void test(){ int a; } //if代码块执行完,变量b就没有了 public void test(){ if(true){ int b; } //这里是访问不到变量b的,编译报错 System.out.println("b = "+b); } 2.java中的操作符(operator) 1)赋值操作符: = 例如: int x=0,i=1,j=1; *= 例如: a*=b 等价于 a=a*b /= 例如: a/=b 等价于 a=a/b; %= 例如: a%=b 等价于 a=a%b; += 例如: a+=b 等价于 a=a+b; -= 例如: a-=b 等价于 a=a-b; 其他的都是类似情况 a+=1; a++ 特殊情况:i++ 和 ++i i++表示先使用i的值,然后再让i自增1。 ++i表示先让i的值自增1,然后再使用i的值。 例如: int a = 1; System.out.println(a++);//1 System.out.println(a);//2 --------------------------------- int b = 1; System.out.println(++b);//2 System.out.println(b);//2 类似的i-- 和 --i也是一样的区别 2)比较操作符 > : 大于 >= : 大于等于 < : 小于 <= : 小于等于 注意:以上操作符只适用于整数类型和浮点数类型; int a=1,b=1; double d=1.0; System.out.println(a>b);//false System.out.println(a<b);//false System.out.println(a>=d);//true System.out.println(a<=b);//true instanceof: 判断一个引用类型变量所指向的对象是不是属于某个类型。 Student s = new Student(); System.out.println(s instanceof Object);//true System.out.println(s instanceof Student);//true //编译报错,因为Student类型和String没有任何子父类关系 System.out.println(s instanceof String); 注意:最终判断的是s所指向对象的类型是不是属于某类型,而不是判断变量s的类型是不是属于某个类型. 例如: Object o = new Student(); 变量o的类型是Object,但是o指向的对象类是Studnet.可以这样写的原因是因为Object是Studnet的父类.这是java的高级特性"多态"的一种表现方式。 3)相等操作符 == : 判断俩个数据 是否 等于 != : 判断俩个数据 是否 不等于 既可以应用在基本类型的比较,也可以应用在引用类型的比较 a.基本类型: int a=1,b=1; float c=1.0f; double d=1.0; //比较的是俩个基本类型数据的值是否相等 System.out.println(a==b); //输出true; System.out.println(a==c); //输出true; System.out.println(a==d); //输出true; System.out.println(c==d); //输出true; b.引用类型: 这两个引用变量必须都引用同一个对象,结果才为true. Student s1 = new Student("zs",25,100); Student s2 = new Student("zs",25,100); //s1中存储的对象内存地址赋给变量s3 Student s3 = s1; //比较俩个引用所指向对象的堆区内存地址是否一样 //俩个对象的内存地址一样相比较才会是true System.out.println(s1 == s2); //输出false; System.out.println(s1 == s3); //输出true; 4)相加操作符 + : 数据类型值相加或字符串连接 a.数据类型值相加 int a=1+2; //a值为3; double b=1+2; //b值为3.0; double b=1+2.0; //c值为3.0; b.字符串连接 System.out.println(1+2+"a"); //输出3a System.out.println(1+2.0+"a");//输出3.0a System.out.println(1+2.0+"a"+true);//输出3.0atrue System.out.println("a"+1+2); //输出a12 System.out.println(1+"a"+2); //输出1a2 / : 整除, 如操作数均为整数,运算结果为商的整数部分 int a1=12/5; //2 int a2=13/5; //2 int a3=-12/5; //-2 int a4=-13/5; //-2 int a5=1/5; //0 double a6=12/5; //2.0 double a7=12/5.0; //2.4 % : 取模操作符, 如操作数均为整数,运算结果为商的整数部分 int a1=1%5; //1 int a2=13%5; //3 double a3=1%5; //1.0 double a4=12%5.1; //1.8000000000000007 5)移位操作符 >> : 算术右移位运算,也称做带符号右移位运算。 注意:正数取反加1得到其对应的负数,负数取反加1得到其对应的正数 int a1 = 12 >> 1; //6; 0000 1100 12 ----------- 0000 110 >>1 ----------- 0000 0110 补位 因为是正数所以补0 结果为6 int a2 = 128 >> 2;//32; int a3 = 129 >> 2;//32; int a5 = -12 >> 1;//-6; 0000 1100 12 --------- 1111 0011 取反 --------- 1111 0100 +1 这个就是-12的二进制形式 ---------- 1111 010 >>1 1111 1010 补位 因为是负数所以补1 这个负数就是最终结果 --------- 0000 0101 取反 --------- 0000 0110 +1 结果为6 所以上面的最终结果是 -6 int a6 = -12 >> 2;//-3; 0000 1100 12 --------- 1111 0011 取反 --------- 1111 0100 +1 这个就是-12的二进制形式 ---------- 1111 01 >>2 1111 1101 补位 因为是负数所以补1 这个负数就是最终结果 --------- 0000 0010 取反 --------- 0000 0011 +1 结果为3 所以上面的最终结果是 -3 >>> : 逻辑右移位运算,也称为不带符号右移位运算。 int a1 = 12 >>> 1;//6; int a2 = -12 >>> 2;//1073741821; 注: a. 对12逻辑右移一位的过程为:舍弃二进制数的最后一位,在二进制数的开头增加一个0; b. 对-12逻辑右移二位的过程为:舍弃二进制数的最后二位,在二进制数的开头增加二个0; << : 左移位运算,也称为不带符号左移位运算。 int a1 = 12 << 1;//24; int a2 = -12 << 2;//-48; int a3 = 128 << 2;//512; int a4 = 129 << 2;//516; 注: a. 对12左移一位的过程为:舍弃二进制数的开头一位,在二进制数的尾部增加一个0; b. 对-12左移二位的过程为:舍弃二进制数的开头二位,在二进制数的尾部增加二个0; 6)位运算操作符 & 与运算 1&1->1, 1&0->0, 0&1->0, 0&0->0; | 或运算 1|1->1, 1|0->1, 0|1->1, 0|0->0; ^ 异或运算 1^1->0, 0^0->0,1^0->1, 0^1->1; 相同为0 不同为1 运算特点: a^0=a; a^a=0; ~ 取反运算 ~1->0, ~0->1; 7)逻辑操作符 短路操作符,如果能根据操作左边的布尔表达式就能推算出整个表达式的布尔值,将不执行操作符右边的布尔表达式; 短路与 && 左边的布尔表达式的值为false, 整个表达式值肯定为false, 此时会忽略执行右边的布尔表达式。 false&&true int a = 1; int b = 2; int c = 3; a>b&&c>b //没有短路功能 a>b&c>b 短路或 || 左边的布尔表达式的值为true, 整个表达式值肯定为true, 此时会忽略执行右边的布尔表达式。 注意:&和&&的区别是什么? |和||的区别是什么? 8)三目运算 形式: 布尔表达式 ? 表达式1 : 表达式2; 如果上面布尔表达式的值为true, 就返回表达式1的值, 否则返回表达式2的值。 例如: int score = 61; String result = (score>=60?"及格":"不及格"); 3.类型转换 1)基本类型之间的转换 隐式转换(自动转换) byte a = 1; //a是byte类型(8位),b是int类型的(32) //编译通过,类型自动转换(隐式转换) int b = a; 特点:小的可以自动转换(隐式转换)为大的,因为无非就是在前面多补几个0而已,不会影响数据值 显式转换 //编译报错,32位的值给8位的变量 int a = 100; byte b = a; //编译通过 //这时候需要类型强制转换(俗称强转,也就是显式转换) int a = 100; byte b = (byte)a; 特点:大的值给小的变量,需要强制转换,但是转换后的结果JVM不会保证还是正确的,因为这是程序员自己的个人行为. 2)引用类型之间的转换 隐式转换 //编译通过,类型自动转换(隐式转换) Student s = new Student(); Object o = s; 特点:子类类型的变量可以自动转换(隐式转换)为父类类型 显式转换 //编译通过,运行后也不报错 //因为引用o本来指向的就是Student对象 Object o = new Student(); Student s = (Student)o; //编译通过,运行后报错 //因为o本来指向的时候Teacher对象 //而Teacher类型对象和Student类型没有任何关系 Object o = new Teacher(); Student s = (Student)o; 4.流程控制-if 程序中if语句的代码块只有满足特定条件的情况下才会被执行. 1)if语句 if(true|false) { //执行代码 } 2)if-else语句 if(true|false){ //执行代码1 }else{ //执行代码2 } 注意:if和else是一组的,二者有且只有一个会执行 3)if-elseif-else if(true|false){ //执行代码1 } else if(true|false){ //执行代码2 } .... else{ //执行代码3 } 注意:以上三个代码块也是一组的,有且只有一个会执行 4)简写形式 不管是if还是elseif还是else,只要其后面执行的代码"只有一句",那么就可以把大括号去掉,执行效果也是一样的。 例如: public void test(int x) { if(x>10) System.out.println("参数大于10"); else if(x>5) System.out.println("参数大于5"); else if(x>0) System.out.println("参数大于0"); else System.out.println("参数小于等于0"); } 5)相关例子 写一个方法实现分时问侯, 如是8点至12点,返回"上午好", 12点至14点,返回"中午好",14点至18点,返回"下午好", 其它时间返回"晚上好"。 注:方法中使用return可以把数据返回给方法的调用者 public String sayHello(int hour) { String msg; if(hour >=8 && hour < 12) msg = "上午好"; else if(hour>=12 && hour <14) msg = "中午好"; else if(hour>=14 && hour <18) msg = "下午好"; else msg = "晚上好"; return msg; } 写一个方法判断某一年是否为闰年 标准:能被4整除,但不能被100整除;或者能被400整除 //返回true表示是闰年,false表示不是闰年 public boolean isLeapYear(int year) { if((year%4==0 && year%100!=0) || (year%400==0)) return true; else return false; } 5.流程控制-switch 使用switch语句完成的功能,使用if语句同样也能完成。但是使用if语句完成的功能,使用switch语句却不一定能完成。不过在某些特定的情况下,switch还是有着自己的独特之处。 1)语法 注意:break关键字表示直接退出整个switch代码块 switch(变量) { case value1: //执行代码1; break; ... case valueN //执行代码n; break; default: //执行代码; break; } 注:switch只能接收byte, short, char或者int类型的变量,如果是JKD1.7那么也可以接收String类型的变量 例如: int day = 4; String result; switch(day) { case 0: result = "星期天"; break; case 1: result = "星期一"; break; case 2: result = "星期二"; break; case 3: result = "星期三"; break; case 4: result = "星期四"; break; case 5: result = "星期五"; break; case 6: result = "星期六"; break; default: result = "参数有误"; break; } System.out.println(day+" : "+result); 2)特殊情况 如果switch的变量与某个case的值匹配,那么就从这个case中的代码开始执行。假如遇到break,就退出整个switch语句,否则依次执行switch语句中后续的case子句,而且不再检查case的值。 例如:写一个方法,返回指定月份有多少天 public int getLastDay(int year, int month) { int day = 30; switch(month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: day=31; break; case 2: day = getLeapYear(year)? 29:28; } return day; } 注意:此处调用的getLeapYear方法就是上面if语句的例子所写的判断一个年份是否是闰年的方法.(在同一个类中,方法之间可以直接调用) 6.循环-for 语法: for(<初始化>; <条件表达式>; <增量>) { //要循环执行的代码 } 直到某一次增量执行后,条件表达式的值为false则循环结束 执行步骤: 1.初始化 2.条件表达式 2.1 false则退出循环 2.2 true则执行循环代码 2.3 执行增量变化 2.4 判断条件表达式 false则退出循环 true则执行循环代码 .... 例如: 使用循环打印10次hello world for(int i=0;i<10;i++){ System.out.println("hello world"); } 例如: 写一个方法,完成计算从1加到100的和 public int sum() { int result = 0; for(int i=1;i<=100;i++) { //result = result + i; result+=i; } return result; } 例如: 写一个方法,完成计算从1加到n的和 public int sum(int n) { int result = 0; for(int i=1;i<=n;i++) { result = result + i; } return result; } 注意:for语句一般用在循环次数事先可确定的情况下 7.循环-while while 语法: while(循环条件) { 循环体 } 当循环条件为true时,就执行循环代码,否则终止循环; 例如: 用while循环完成计算从1加到n的和 public int sum(int n) { int result = 0; int i=1; while(i<=n) { result = result + i; i++; } return result; } do-while 和while非常类似,只不过先执行循环体,然后再判断循环条件. 语法: do{ 循环体 } while(循环条件); 例如: 用do-while循环完成计算从1加到n的和 public int sum(int n) { int result = 0; int i = 1; do { result = result + i; i++; } while(i<=n) return result; } 注意:while和do-while循环用在循环次数事先不可确定的情况下 8.循环的嵌套 例如:打印出五行每行十个☆ //这个循环可以打出五个换行 for(int i=0;i<5;i++){ System.out.println(); } //这个循环可以连着打印出10个☆ //但是不会换行 //注意print方法和println方法的区别 for(int j=0;j<10;j++){ System.out.print("☆"); } 那么把俩个循环嵌套在一起即可完成功能 for(int i=0;i<5;i++){ for(int j=0;j<10;j++){ System.out.print("☆"); } System.out.println(); } 例如: 往控制台上输出以下内容: * ** *** **** ***** ****** ******* public void print(int n){ for(int i=0;i<n;i++){ for(int j=0;j<i+1;j++){ System.out.print("*"); } System.out.println(); } } 9.break和continue 注:break和continue一般都是要结合循环使用的(for/while/do-while) break 终止当前或指定循环 for(int i=0;i<10;i++){ if(i==3){ break; } System.out.println("i = "+i); } 输出结果: i = 0 i = 1 i = 2 continue 跳过本次循环,执行下一次循环 for(int i=0;i<10;i++){ if(i==3){ continue; } System.out.println("i = "+i); } 输出结果: i = 0 i = 1 i = 2 i = 4 i = 5 i = 6 i = 7 i = 8 i = 9 10.label标签 在循环嵌套的时候,使用label可以让break或者continue作用到指定的循环上,否则break或者continue只会默认作用到当前所处的循环上。 例如: 这个break跳出的是当前循环(也就是这里的内循环) for(int i=0;i<3;i++){ for(int j=0;j<5;j++){ if(j==3){ break; } System.out.println("j = "+j); } } 输出结果: j = 0 j = 1 j = 2 j = 0 j = 1 j = 2 j = 0 j = 1 j = 2 例如:这个break跳出的是外循环(因为使用了label) f1:for(int i=0;i<3;i++){ for(int j=0;j<5;j++){ if(j==3){ break f1; } System.out.println("j = "+j); } } 输出结果: j = 0 j = 1 j = 2
java_day03_流程控制
猜你喜欢
转载自www.cnblogs.com/yue-170305/p/11478907.html
今日推荐
周排行