表达式和流控制语句
3.1.变量和作用范围
3.1.1.局部变量
1,在代码块中声明的变量为局部变量
public class Hello{
int num = 1;//这个num不是局部变量
public void show(){
int age = 10;//这个age是局部变量
}
}
2,在方法参数列表位置声明
public class Hello{
public void eat(String food){}//这里的food是局部变量
}
3,局部变量只能在当前代码块或者子代码块中使用.
例1:
public void eat(String food){//①
int age = 10;
}//②
局部变量age只能在 ①②中间使用
例2:
public void eat(String food){//①
{//②
int age = 10;
}//③
{//④
System.out.println(age);//这里是否能使用age?
}//⑤
}//⑥
int age 是局部变量,是在②③代码块中声明的,所以只能在②③代码块中使用,所以在④⑤代码块中不能使用到,编译会有错误。
3.1.2.实例变量
1,在类中,方法外声明的变量为实例变量,也叫成员变量。
public class Hello{
int num = 1;//这个num是实例变量
public void show(){
int age = 10;//这个age不是实例变量
}
}
2,实例变量可以在当前类的所有非静态代码块/方法中使用
class Hello{
int age = 10;
public static void main(String[] args){
System.out.println(age);//1
}
public void show(){
System.out.println(age);//2
}
public static void eat(){
System.out.println(age);//3
}
}
在1 2 3 哪个位置访问是正确的?为什么?
1号位置不可以访问,main方法为static方法不能访问非静态的成员变量。
2号位置可以访问,普通方法可以访问普通的成员变量。
3 号位置不可以访问,eat是静态方法。
3,实例变量有初始值。
int byte short long 默认赋值 0
double float 默认赋值0.0
boolean 默认赋值 false
char 默认赋值 0
引用数据类型 默认赋值为 null
class Hello{
int age;
public void show(){
System.out.println(age);//1
}
}
在1处的打印语句能打印什么内容?
打印0
虽然没有显示赋值,但是由于age是成员变量,成员变量会默认赋值,所以1处会打印0
3.2.操作符
3.2.1.赋值操作符
1, = 赋值 把等号右边的值赋值给等号左边的变量
2, *= 乘等 a*=b <===> a = a * b;
3, /= 除等 a/=b <===> a = a / b;
4,%= 余等 a%=b <===> a = a% b;
5,+= 加等 a+=b <===> a = a + b;
6, -= 减等 a-=b <===> a = a - b;
7, <<= 左移等 a<<=b <===> a = a << b;
8, >>= 右移等 a>>=b <===> a = a >> b;
9,&= 与等 a&=b <===> a = a & b;
10, ^= 非等 a^=b <===> a = a ^ b;
11, |= 或等 a|=b <===> a = a | b;
3.2.2.比较运算符
比较运算符,最后的返回结果为boolean类型。
1, > 大于 10 > 4 返回 true
2, >= 大于等于 10 > =4 返回 true
3, < 小于 10 < 4 返回 false
4, <= 小于等于 10 <= 4 返回 false
5, instanceof 大于 stu instanceof Object 返回 true
用来判断某一个对象是否属于某一个数据类型
6, == 等于 10 == 4 返回 false
等等是比较内存地址
7, != 不等于 10 != 4 返回 true
3.2.3.算术运算符
1, + 加 1+1 结果为 2
2, - 减 1-1 结果为0
3, * 乘 1*1 结果为 1
4, / 除 1/1 结果为 1
3.2.4.移位运算符
1, >> 有符号右移
10>>2 数字10 右移两位
首先把10换算为二进制数 0000 1010
然后把这个数向右移动两位 0000 10
前面空的两位补0 补满8位 000000 10
这个就是最后的结果,转换为10进账数是 2
2, << 有符号左移
10<<2 把数字10 左移两位
首先把10换算为二进制数 0000 1010
然后把这个数向左移动两位 00 1010
前面空的两位补0 补满8位 00 101000
这个就是最后的结果,转换为10进账数是 40
3, >>> 无符号右移
无符号右移,正数补0 负数补1
其他和上面逻辑一致
3.2.5.位运算符
1, & 与 全1为1 有0为0
0 & 0 --> 0
0 & 1 --> 0
1 & 0 --> 0
1 & 1 --> 1
2, | 或 全0为0 有1为1
0 | 0 --> 0
0 | 1 --> 1
1 | 0 --> 1
1 | 1 --> 1
3, ^异或:相同为0,不同为1
1^1 --> 0
1^0 --> 1,
0^1 --> 1,
0^0 --> 0
4,~取反:,
~1 --> 0
~0 --> 1,
3.2.6.逻辑运算符
1, && 双与,有短路效果
true && true --> true
true && false --> false
false && true --> false
false && false --> false
当双与前面的条件为 false 时双与后面的条件不执行
2, || 双或,有短路效果
true || true --> true
true || false --> true
false || true --> true
false || false --> false
当双或前面的条件为 true 时双或后面的条件不执行
例1:
public void show(){
int i = 0;
int j = 0;
if( ( i > 1 ) && ( i++ > 1) ){
}
System.out.println(i);//这里打印i为0
}
因为 i > 1 返回false 当双与的前面为false时,后面不执行,这个是短路效果.
3.2.7.三目运算符
(布尔表达式) ? (操作1) : (操作2);
3.3.类型转换
样例:
package sample;
public class CastingTest {
public void implictCasting() {
byte a = 0x60;
int ia = a;
char b = 'a';
int c = b;
long d = c;
long e = 1000000000L;
float f = e;
double g = f;
String s = "hello";
Object o = s;
}
public void explicitCasting() {
long l = 1000000L;
int i = l; //(int)l;
double d = 12345.678;
float f = d; //(float)d;
Object o = new String("Hello");
String str = o; //(String)o;
}
}
基本数据类型之间的转换:
1,需要知道基本数据类型对应的长度为多少
2,大长度的值 赋值 给小长度的值需要强制转换
例:
long l = 10L;
int i = l;//编译错误
修改为:
int i = (int)l;
3,小长度的值 赋值 给大长度的值不需要转换,直接赋值即可
例:
int i = 10;
long l = i;//编译运行正常
3.4.条件控制语句
3.4.1.if语句
1,if 语句
语法: if(boolean表达式){
//如果表达式为true执行的代码
}
例:
int age = 96;
if(age<100 && age>0){
System.out.println(“这个学生虽然”+age+“岁了,但是我学校收了。”);
}
2, if else 语句
语法 : if(boolean表达式){
//如果表达式为true执行的代码
}else{
//如果表达式为false执行的代码
}
例:
// if else 语句
int count = 12;
if(count>100){
System.out.println(“这个学校人数大于100”);
}else{
System.out.println(“学校人数为:”+count);
}
3, if else if else if else 语句
语法 if(boolean表达式){
//如果表达式为true执行的代码
}else if(boolean表达式){
//如果表达式为true执行的代码
}else if(boolean表达式){
//如果表达式为true执行的代码
}else{
//如果表达式为false执行的代码
}
注:一个if 系列的语句只会有一段代码被执行。
例:
int num = 2;
if(num<16){
System.out.println(“这个人”+num+“岁,还是个小孩”);
}else if( num<=18){
System.out.println(“这个人”+num+“岁,是个青年”);
}else if(num<30){
System.out.println(“这个人”+num+“岁,是个年轻力壮,适合写代码”);
}else if(num== 40){
System.out.println(“这个人”+num+“岁,是个 一枝花”);
}else{
System.out.println(“这个人”+num+“岁,干啥啥不行,吃嘛嘛不剩.”);
}
//本例打印这个人2岁,还是个小孩
分析:虽然num满足多个条件,但是从上到下优先匹配,首先满足了第一个if条件,即执行第一个if的代码块,执行完这个代码块以后就跳出了if判断。所以只执行了一个代码块。
3.4.2.switch语句
可以理解为switch是简化的if语句,其中的boolean表达式只做等于比较。
语法:
int num = 3;
switch (num) {
case value:{}
case value:{}
case value:{}
case value:{}
default:{}
}
解释:
这里switch语句是用变量num的值分别和case后面的value进行== 比较,如果相同就会执行case冒号后面的代码块,当某一个case满足比较以后,这个case下面所有的case都不会进行== 判断,只会直接执行 冒号后的代码块。
例:
int num = 3;
switch (num) {
case 1:
System.out.println(“一生一世”);
case 2:
System.out.println(“二龙戏珠”);
case 3:
System.out.println(“三头六臂”);
case 4:
System.out.println(“四通八达”);
default:
System.out.println(“废了…想不到…”);
break;
}
会打印:
三头六臂
四通八达
废了…想不到…
解释:当使用num 和case 3 中的3 进行== 比较以后,返回true,比较成功
那么case 3下面所有的value值都不会和num进行比较,而直接执行代码块,所以打印结果如上。
这里的 switch()里 都支持哪些类型呢?
基本数据类型:byte, short, char, int
包装数据类型:Byte, Short, Character, Integer
枚举类型:Enum
字符串类型:String(Jdk 7+ 开始支持)
3.5.循环语句
3.5.1.for循环
重复的执行某一段代码,这个是循环的本质。
语法: for(初始化部分:循环条件:迭代部分){
循环体
}
初始化部分:用来设置循环的一些初始条件,比如循环控制变量的初始值;
可以不要
循环条件: 这是一个布尔表达式,每一次循环都要对该表达式求值,以判断到底 继续循环还是终止循环。
必须要
循环体: 这是循环操作的主体内容,可以是一条语句,也可以是多条语句;
可以不要
迭代部分: 用来改变循环控制变量的值,从而改变循环条件表达式的值;
可以不要
for代码执行流程:
1,执行 初始化部分
2,判断 循环条件 满足
3,执行 循环体
4,执行 迭代部分
5,判断 循环条件 满足
6,执行 循环体
7,执行 迭代部分
…
n,判断 循环条件 不满足
n+1, 跳出循环
例:
//用于累加的变量
int num = 0;
//初始化部分为 int i=1;
//循环条件为 1<=100;
//迭代部分为 i++;
//循环体为 num+=i;
//根据文档提示的执行流程 。推出结果。
for(int i =1;i<=100;i++){
num+=i;
}
System.out.println(num);
3.5.2.while 循环
语法:while(循环条件){
循环体
}
while代码执行流程:
1,判断循环条件 满足
2,执行循环体
3,判断循环条件 满足
4,执行循环体
…
n,判断循环条件 不满足
n+1,跳出循环
例:
//用于累加的数字
int num = 0;
//语法中没有初始化部分 手动添加 初始化部分 : int i = 1;
int i =1;
while(i<=100){
num+=i;
i++;//手动添加 迭代部分
}
System.out.println(num);
3.5.3.do_while语句
语法:do{
循环体
}while(循环条件);
do—while循环执行流程:
1,执行循环体
2,判断循环条件 满足
3,执行循环体
4,判断循环条件 满足
5,执行循环体
…
n,判断循环条件 不满足
n+1,跳出循环
例: //用于累加的数字
int num = 0;
//语法中没有初始化部分 手动添加 初始化部分 : int i = 1;
int i =1;
do{
num+=i;
i++;//手动添加 迭代部分
}while(i<=100);
System.out.println(num);
3.6.跳出循环
3.6.1.break
跳出当前循环
for(int i = 0;i<9;i++){
if(i== 5){
break;
}
System.out.println("break: "+i);
}
System.out.println(“结束”);
当i== 5的时候会跳出循环 向下执行循环外面的代码
break跳出本次循环后即使下一次满足循环的条件也
不会执行循环内容
3.6.2.continue
跳过本次循环进入下一次循环
for(int i = 1;i<=9;i++){
if(i== 5){
continue;
}
System.out.println("continue: "+i);
}
System.out.println(“结束”);
当i==5会跳过当前循环,进入下一次循环,就是会直接去执行循环的迭代部分,然后执行循环条件…
continue跳出本次循环后如果下一次满足循环的条件
会继续执行循环内容
3.6.3.break lable和continue lable
可以给循环指定一个lable,然后再break 语句后编写lable,表示跳出指定的lable循环
eg:
f1:for(int i = 0;i<10;i++){
for(int j = 0;j<10;j++){
if(j== 5){
break f1;//①
}
}
}
①表示当执行该代码时会跳出f1循环执行f1循环外面的代码
f1:for(int i = 0;i<10;i++){
for(int j = 0;j<10;j++){
if(j==5){
continue f1;//②
}
}
}
②表示当执行该代码时会跳过f1的本次循环,执行下一个循环。