运算符
运算符
运算符优先级
() > 单目优先级 > 双目运算 > 三目运算 > =
表达式求值
表达式求值在Java内部是用两个栈来实现的,包括运算符栈+操作数栈,要从这个角度理解运算符的优先级,“表达式求值”问题,两个核心关键点:
- 双栈,一个操作数栈,一个运算符栈;
- 运算符优先级,栈顶运算符,和,即将入栈的运算符的优先级比较:
如果栈顶的运算符优先级低,新运算符直接入栈
如果栈顶的运算符优先级高,先出栈计算,新运算符再入栈
表达式求值
运算符相关
-
Java中涉及byte、short和char类型的运算操作首先会把这些值转换为int类型(结果可能会超出原有的表达范围,所以直接隐式转化为int),然后对int类型值进行运算,最后得到int类型的结果。例如int+short返回的值为int,short+short返回的值也是int.
- final,可以抑制隐式转换
- +=,*=,>>=是混合赋值运算符,可以抑制隐式转换(单目运算符加=号不改变类型)
-
a++与++a的区别:a++ 和 ++a的相同点都是给a+1,不同点是a++是先参加程序的运行再+1,而++a则是先+1再参加程序的运行
-
for
for (int i=0;i<list.size;i++) { 这样进行遍历 中间可以break或者continue; } for (String str: list) 用迭代器的方式进行遍历
-
switch
switch(expression){ case value: break; case value: break; default: }
-
switch 语句中的变量类型可以是: byte、short、int 或者 char。从 Java SE 7 开始,switch 支持字符串 String 类型了,同时 case 标签必须为字符串常量或字面量。
-
switch 语句可以拥有多个 case 语句。每个 case 后面跟一个要比较的值和冒号。
-
case 语句中的值的数据类型必须与变量的数据类型相同,而且只能是常量或者字面常量。
-
当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到 break 语句出现才会跳出 switch 语句。
-
当遇到 break 语句时,switch 语句终止。程序跳转到 switch 语句后面的语句执行。case 语句不必须要包含 break 语句。如果没有 break 语句出现,程序会继续执行下一条 case 语句,直到出现 break 语句。
-
switch 语句可以包含一个 default 分支,该分支一般是 switch 语句的最后一个分支(可以在任何位置,但建议在最后一个)。default 在没有 case 语句的值和变量值相等的时候执行。default 分支不需要 break 语句。
-
-
逻辑运算符中,&与&&,|与||的区别:
在java的逻辑运算符中,有这么四类:&&(短路与),&,|,||(短路或)。
&&和&都是表示与,区别是&&只要第一个条件不满足,后面条件就不再判断。而&要对所有的条件都进行判断。
||和|都是表示“或”,区别是||只要满足第一个条件,后面的条件就不再判断,而|要对所有的条件进行判断。 -
java中的位运算符:
位运算符主要针对二进制,它包括了:位与( & ) 、位或( | )、位非( ~ )、位异或( ^ )。从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算(比如条件1&条件2),而位运算符主要针对两个二进制数的位进行逻辑运算。
除了位非( ~ )是一元操作符外,其它的都是二元操作符。
例如:
System.out.println(5 & 3);//结果为1。位与:第一个操作数的的第n位于第二个操作数的第n位如果都是1,那么结果的第n位也为1,否则为0
System.out.println(5 | 3);//结果为7。位或操作:第一个操作数的的第n位于第二个操作数的第n位 只要有一个是1,那么结果的第n位也为1,否则为0
System.out.println(5 ^ 3);//结果为6。位异或:第一个操作数的的第n位于第二个操作数的第n位 相反,那么结果的第n位也为1,否则为0
System.out.println(~5);//结果为-6 。位非:操作数的第n位为1,那么结果的第n位为0,否则为0 -
移位运算符
java中有三种移位运算符
-
value << num(左移运算符<<):
- num 指定要移位值value 移动的位数。
- 左移的规则只记住一点:丢弃高位,0补低位。(舍弃符号位)
- 如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模。如对int型移动33位,实际上只移动了332=1位。
-
value >> num(右移运算符>>):
- num 指定要移位值value 移动的位数。
- 右移的规则只记住一点:丢弃低位,左补符号(保存符号位)
-
value >>> num (无符号右移运算符>>>):
- num 指定要移位值value 移动的位数。
- 无符号右移的规则只记住一点:丢弃低位,0补高位(舍弃符号位)
-
运算符面试题
-
【华为笔试题】【单选题】
public class Test{ static boolean foo(char c) { System.out.print(c); return true; } public static void main(String[] args) { int i=0; for (foo('A');foo('B') && (i<2);foo('C')) { i++; foo('D') } } }
- ABDCBDCB
-
【腾讯笔试题】【单选题】
在java7中,下列不能做switch()的参数类型是?
A. 整型 B. 枚举类型 C. 字符串 D. 浮点型- 正确答案为D
【答案解析】
在switch(expr1)中,expr1只能是一个整数表达式或者枚举常量,整数表达式可以是int基本类型或Integer包装类型,由于,byte,short,char都可以隐含转换为int,所以,这些类型以及这些类型的包装类型也是可以的。显然,long、float、double类型不符合switch的语法规定,并且不能被隐式转换成int类型,所以,它们不能作用于swtich语句中。
注意:String类型是Java7开始支持的。
- 正确答案为D
-
以下代码的输出结果为:
public static void main(String[] args) { System.out.println("value="+switchit(4)); } public static int switchit(int x) { int j = 1; switch (x) { case 1:j++; case 2:j++; case 3:j++; case 4:j++; case 5:j++; default: j++; } return j+x; }
- 8
-
【不定向选择】会抛出NullPointerException异常的有
根据下面的代码,
String s = null;
会抛出NullPointerException异常的有()。
A. if( (s!=null) & (s.length()>0) )
B. if( (s!=null) && (s.length()>0) )
C. if( (s==
null) | (s.length()==
0) )
D. if( (s==
null) || (s.length()==
0) )- A,C
-
【阿里巴巴笔试题】【单选题】
经过强制类型转换以后,变量a, b的值分别为( )
short a = 128; byte b = (byte) a;
A. 128 127
B. 128 -128
C. 128 128
D. 编译错误-
正确答案为:B
【答案解析】此题需要复习一下源码,反码与补码byte在内存中占一个字节,范围是 -128到127之间。
将128强制类型转换为byte型,就超出了byte型的范围,
128的二进制存储是 1000 0000 转换为byte型后,最高位是符号位,值是-128
-
-
a++与++a的区别,以下代码的输出为:
public static void main(String[] args) { // TODO Auto-generated method stub int j = 0 ; for(int i = 0 ; i < 100 ; i++){ j = j++ ; } System.out.println(j); }
-
Java编译器每次遇到自增、自减运算符的时候都会开辟一块新的内存空间来保存赋值之前j的值。JVM里面有两个存储区,一个是暂存区(以下称为堆栈),另一个是变量区。j=j++是先将j的值(0,原始值)存入堆栈中(对应图中分配一块新的内存空间),然后对变量区中j自加1,这时j的值确实是1,但随后将堆栈中的值赋给变量区的j,所以最后j=0;
j=j++ //j=j+1; //temp=j; //j=temp; j=++j //j=j+1; //temp=j; //j=temp;
-