Java运算符优先级分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.zt.javase01;
 
public class Test2 {
    public static void main(String[] args) {
        int n = 10;
        n += (n++) + (++n);
        System.out.println(n);//输出32
 
        /*
 
 
         (n++) (++n)
            从左到右执行
            因此(n++)表达式的值10 n的值变为了11
            (++n) 的表达式的值变为了12 n的值变为了12
         +  (n++)+(++n)整个表达式的值变为了22
         += n+=的这个n不好分析, 要分析得从操作数栈和局部变量表的角度
        */
 
        /*
        *
        字节码分析 下面是用javap反编译class得到的字节码指令指令<br>        方法执行时栈有局部变量表和操作数栈区域, 局部变量表一般存储变量, 操作数栈是用来运算的, 但是i++和==i对应的inc指令可以不通过操作数栈直接为局部变量自增
        javap -c com.zt.javase01.Test2
Compiled from "Test2.java"
public class com.zt.javase01.Test2 {
  public com.zt.javase01.Test2();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
 
  public static void main(java.lang.String[]);
    Code:
       0: bipush        10  //将10压到操作数栈 此时栈中数据为10
       2: istore_1   //从操作数栈中弹出10保存到局部变量表第1个槽位   int n = 10;
       3: iload_1 //从局部变量表取10 取到操作数栈 此时栈中数据 10 n+=的n入操作数栈
       4: iload_1 //从局部变量表取10 到操作数栈 此时栈中数据 10 10 n++的n入操作数栈
       5: iinc          1, 1   //局部变量表中第1槽的值自增1变为11 n++
       8: iinc          1, 1   //局部变量表中第1槽的值自增1变为12 ++n
      11: iload_1   //从局部变量表中取值12到操作数栈 此时栈中数据 12 10 10 ++n的n入操作数栈
      12: iadd //求和 从栈中弹出12 10求和并压到栈顶 也就是现在栈变成了 22 10 求(n++)和(++n)的值
      13: iadd  //弹出22和12 求和 得到32
      14: istore_1 // 从操作数栈弹出32放到局部变量表1的位置
      15: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream; //获取对象
      18: iload_1 //从局部变量表读取数值32
      19: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V  //打印
      22: return
}
 
Process finished with exit code 0
        *
        * */
    }
}<br><br>字节码指令官方文档:<br>https://docs.oracle.com/javase/specs/jvms/se19/html/jvms-6.html#jvms-6.5.iload_n<br><br>关于运算符的结合性<br>a 运算符1 b 运算符2 c<br>结合性不是决定运算符1和运算符2哪个先计算<br>而是决定了运算符优先级相同时 表达式实际是<br>(a 运算符1 b) 运算符2 c<br>还是<br>a 运算符1 (b 运算符c)<br>例如

 

 

int x=100, y=0;
int result= x > y ? 100 : ++y > 2 ? 20 : 30;

上面表达式如果条件运算符是右结合那相当于下面的表达式

x>y?100:  (++y>2?20:30) 结果为100

如果条件运算符是左结合相当于下面的表达式

 (x>y?100:++y)  >2?20:30  结果为20

最终执行代码验证

System.out.println(result);

输出100证明是右结合

 

 

  

posted @   为了生活更好  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示