运算符

运算符

运算符优先级

() > 单目优先级 > 双目运算 > 三目运算 > =

表达式求值

表达式求值在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开始支持的。
  • 以下代码的输出结果为:

            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;
      
posted @ 2022-06-08 13:01  Faetbwac  阅读(98)  评论(0编辑  收藏  举报