深入理解Java中i++和++i

ROS2_IGH方案配置(二)——Ubuntu22.04 实时内核性能验证与调优 本文详细介绍了在Ubuntu22.04系统上配置ROS2_IGH方案时,如何验证调优PREEMPT_RT实时内核性能。通过使用cyclictest工具进行基准测试压力测试,分析中断与硬件延迟,并优化内核参数,确保系统满足工业控制领域对硬实时性的苛刻要求。文章还提供了针对ROS2的特殊优化建议性能监控方案,帮助开发者实现毫秒级延迟的稳定控制。 阅读详情

在几乎所有的命令式编程语言中,必然都会有i++和++i这种语法。有些语言中i++和++i既可以作为左值又可以作为右值,在Java语言中,这两条语句都只能作为右值,而不能作为左值。同时,它们都可以作为独立的一条指令执行。

可以看到程序中 ++a =  5; 和 a++ = 5;报错了。 

下面说明i++和++i的实现原理:

首先写一个例子:

{
    int i = 1;
    int j1 = i++;
    System.out.println("j1=" + j1); // 输出 j1=1
    System.out.println("i=" + i); // 输出 i=2
}

{
    int i = 1;
    int j2 = ++i;
    System.out.println("j2=" + j2); // 输出 j2=2
    System.out.println("i=" + i); // 输出 i=2
}

由结果可以看出无论是i++和++i指令,对于i变量本身来说是没有任何区别,指令执行的结果都是i变量的值加1。而对于j1和j2来说,这就是区别所在。

int i = 1;
int j1 = i++; // 先将i的原始值(1)赋值给变量j1(1),然后i变量的值加1
int j1 = ++i; // 先将i变量的值加1,然后将i的当前值(2)赋值给变量j1(2)

 接下来让我们深入到编译后的字节码层面上来了解i++和++i的实现原理,为了方便对比,笔者将这两个指令分别放在2个不同的方法中执行,源代码如下:

public class Test {

    public void testIPlus() {
        int i = 0;
        int j = i++;
    }

    public void testPlusI() {
        int i = 0;
        int j = ++i;
    }

}

 将上面的源代码编译之后,查看编译生成的代码(忽略次要代码)如下:

...
{
  ... 

  public void testIPlus();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=3, args_size=1
         0: iconst_0               // 生成整数0
         1: istore_1               // 将整数0赋值给1号存储单元(即变量i)
         2: iload_1                // 将1号存储单元的值加载到数据栈(此时 i=0,栈顶值为0)
         3: iinc          1, 1     // 1号存储单元的值+1(此时 i=1)
         6: istore_2               // 将数据栈顶的值(0)取出来赋值给2号存储单元(即变量j,此时i=1,j=0)
         7: return                 // 返回时:i=1,j=0
      LineNumberTable:
        line 4: 0
        line 5: 2
        line 6: 7

  public void testPlusI();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=3, args_size=1
         0: iconst_0                // 生成整数0
         1: istore_1                // 将整数0赋值给1号存储单元(即变量i)
         2: iinc          1, 1      // 1号存储单元的值+1(此时 i=1)
         5: iload_1                 // 将1号存储单元的值加载到数据栈(此时 i=1,栈顶值为1)
         6: istore_2                // 将数据栈顶的值(1)取出来赋值给2号存储单元(即变量j,此时i=1,j=1)
         7: return                  // 返回时:i=1,j=1
      LineNumberTable:
        line 9: 0
        line 10: 2
        line 11: 7
}
...

下面举个面试题的例子如下: 

下面程序是否存在问题?如果存在,请指出问题所在,如果不存在,说明输出结果。
package www;

public class Test {
public static void main(String[] args) {
	Test test = new Test();
	int i =0;
	test.increase(i); //完成方法调用之后i = 0 ,因为方法increase是值传递,因此对形参的修改不会影响到实参的值。(参数列表里传进去的值为实参i的副本)
	/**
	 * i=++i;
	 */
	//上面代码出现警告The assignment to variable i has no effect 警告的意思是将值赋给变量i毫无作用,并不会改变i的值。也就是说:i = ++i等价于++i
	
	i=i++;
	System.out.println(i);
		
}

void increase(int i) {
	i++;
}
}

 该问题答案是不存在问题,输出结果为0

解释如下:

1、首先对方法increase的调用是值传递,参数列表里传的是实参的拷贝,因此在方法里对形参的修改不会影响到实参的值,所以在执行完increase方法的调用之后,main方法中i的值还是0。

2、对于i = i ++ ;

i++的实现原理为:

1、把变量i的值取出来,放在一个临时变量tmp里。

2、变量i执行自增操作。

3、把临时变量tmp的值作为自增运算的结果返回。

所以对于i = i++; 相当于执行了下面三行代码:

1)tmp=i; //把i的值保存到tmp ,tmp = 0

2)i = i + 1; //执行自增操作,i = 1

3)i= tmp; //将tmp的值赋值给i ,此时 i = 0

所以最终程序运行结果为0。

如果将 i = i ++ ; 变成 i = ++ i;则运行结果为 1 。 因为++i是先执行i自增,然后才赋值给左侧变量。

但同时Eclipse IDE中抛出【The assignment to variable i has no effect】警告,警告的意思是将值赋给变量i毫无作用,并不会改变i的值。也就是说:i = ++i等价于++i

 

揭秘Synopsys EDA中的AI黑科技:DSO.ai如何改变传统芯片设计流程 本文深入探讨了Synopsys EDA中的AI黑科技DSO.ai如何革新传统芯片设计流程。通过数据驱动的方法论、功耗优化革命时序收敛智能加速,DSO.ai显著提升了设计效率质量,实现了从经验驱动到AI驱动的范式转变。文章还提供了实战指南,帮助团队跨越AI EDA的实施鸿沟。 阅读详情

相关推荐

信道估计准则演进:从LS、MMSE到LMMSE的工程权衡

本文深入探讨了信道估计准则的演进历程,从LS、MMSE到LMMSE的工程权衡。通过对比分析三大经典算法的数学本质、工程实现及适用场景,揭示了在计算复杂度、实时性性能之间的关键取舍。文章结合4G/5G基站项目实战经验,提供了算法选型的三维决策模型前沿发展建议,为无线通信系统设计提供实用指导。

weixin_29327525的博客 246

Java中的i++++i

1.j=i++j=++i的底层操作   前提条件:假定i,j只是一个局部变量,i为第一个局部变量,j为第二个局部变量,i=10,j=2,单纯看j=i++j=++i在底层到底做了哪些操作。   首先看一下几个字节码指令(实际运行可能为其他指令,具体可通过javap查看字节码文件):     iload_0:将第一个int型本地变量推送至栈顶     iStore_0:将栈顶int型数值存入到第一...

zz1x2c3的博客 1536

Open3D点云数据处理(六):点云、mesh可视化(Visualizer类)

本文介绍了Open3D中Visualizer类可视化几何对象的方法,给出了常用参数解释代码示例。

孙悟空 2964

你真的理解了C语言++--运算符么?

       这个主题对于刚开始学习C语言时可能会觉得很简单啊,那好你告诉我下面几个题目的输出是什么,你要是能说对,并且说出为什么,那你就可以不用往下看了       int i = 0,j = 0;       1、j = (i++)+(i++)+(i++);  //而不是j = i++i++i++;       2、j = (++i)+(++i)+(++i); //而不是j = ++i++i+...

liuchunjie11的博客 1万+

i = i++j = ++j 到底做了什么?

public class TestClass { public void fun() { int i = 0; i = i++; int j = 0; j = ++j; } } public void fun(); descriptor: ()V flags: ACC_PUBLIC ...

weixin_43960292的博客 1714

java i=i++j=i++的区别

i=i++;j=i++的区别 i=i++-----------在java中 这个语句的前后顺序应该是这样的(tmp=i;i++;tmp==i) java的编译器在遇到i++i- -的时候会重新为变量运算分配一块内存空间,以存放原始的值,而在完成了赋值运算之后,将这块内存释放掉,下面首先看一下如果是j=i++的情况:   i的原始值存放在后开辟的内存中,最后这个值将赋值给j,这样j=i++...

小仙女的博客 2万+

浅析C语言中“++”、“- -”等缩略写法

初学C语言,不难发现,许多基本例题都会用到“i++”、“++i”等简写,稍有不慎,就很容易弄混,下面就让我们来细致分析下,这些简写究竟代表什么,如何区别开来。 1.“++“- -” 举个例子,int i=10;int j; 那么j=++i; j=- -i;j=i++;j=i- -中,ji的值分别为多少? j=++i,可以看成两步: 1.i=i+1=10+1=11; 2.j=i=11; 同...

weixin_43823473的博客 4404

深入理解java中i++++i的区别

老谭带你深入理解java中i++++i的区别 最近老谭在面试中频频遇到i++++i之类的基础题目,但是细思之下,其实这道题目可是一点也不简单呐,其中涉及:java基础运算操作、JVM运行时环境、JVM栈内存操作、JVM指令、甚至并发多线程等。下面我就来谈谈我对此的理解(如有理解不到位的地方请指教,如有收货也请不要吝啬您的赞,因为您小手一挥就是对我莫大的支持)。 PS:①:java源文件经jav...

github_34793283的博客 1504

深入理解Java中的i++++i语句

在很多高级编程语言中,都会有i++++i这种语法。例如在Java语言中,这两条语句都只能作为右值,而不能作为左值。同时,它们都可以作为独立的一条指令执行。下面用示例来讲解一下这两条语句。 int i = 0; int j = i++; // 正确 int k = ++i; // 正确 i++; // 正确 ++i; // 正确 i++ = 3; // 编译不通过 ++i = 3; // 编译不通过 关于i++++i的区别,大家应该都是有所了解的,本文将通过实例来简单地解释一下。 { int

RayPick的博客 3680

java ii的区别_深入理解java中i++++i的区别

今天简单谈谈关于java的一个误区,相信很多刚开始学习java的朋友都会遇到这个问题,虽然问题很简单,但是经常容易搞混,说说java的i++++i的区别。先看一下代码:public class test {public static void main(String[] args) {int i = 0;for (int j = 0; j < 10; j++) {i=i++;}System...

weixin_42517623的博客 760

java i i_深入理解java中i++++i的区别

今天简单谈谈关于java的一个误区,相信很多刚开始学习java的朋友都会遇到这个问题,虽然问题很简单,但是经常容易搞混,说说java的i++++i的区别。先看一下代码:public class test {public static void main(String[] args) {int i = 0;for (int j = 0; j < 10; j++) {i=i++;}System...

weixin_29826879的博客 215

日常学习Java:i++++i的深入理解

i++++i的深入理解 最终执行结果是多少? 平常我们会说因为j++每次得到的都是0.所以结果为0;也就是大家经常说的j++是先用j后自增,++j是先自增后用j。 为什么呢? 涉及jvm的虚拟机栈 虚拟机栈 虚拟机栈是线程私有的,每创建一个线程,虚拟机就会为这个线程创建一个虚拟机栈,虚拟机栈表示Java方法执行的内存模型,每调用一个方法就会为每个方法生成一个栈帧(Stack Frame),用...

qq_41574332的博客 594

java中i i 区别_深入理解java中i++++i的区别

今天简单谈谈关于java的一个误区,相信很多刚开始学习java的朋友都会遇到这个问题,虽然问题很简单,但是经常容易搞混,说说java的i++++i的区别。先看一下代码:public class test {public static void main(String[] args) {int i = 0;for (int j = 0; j < 10; j++) {i=i++;}System...

weixin_31925811的博客 405

java自增变量_Java 自增运算 i++ ++i 的深入理解

简单理解:i++ 是先运算后自增++i 是先自增后运算虚拟机执行原理java代码public static void main(String[] args){int num = 10;int a = num++;System.out.println(" a = "+a+"\n num = "+num);}编译后代码public static void main(String[] args) {in...

weixin_31304599的博客 496

一看就懂的i++++i详解

一看就懂的i++++i详解 前言 我相信很多朋友可能之前已经百度过i++++i的相关文章了,也做过不少的练习,觉得自己已经深刻掌握了它们之间的原理了,真的是这样的吗?来试试计算一下我下面提供的几道练习,你就会发现你又不会了! 示例代码 请先自己心算一下答案,然后找个本子记下来,然后再跟我后面的答案对比,看你能做对几道题,能做对两题以上的我喊你大哥!! 示例1 int i = 0; i = i++; System.out.println("i = " + i); 123 示例2 int a = 2;

song854601134的博客 3万+

一篇文章彻底弄懂 i++++i

一篇文章彻底弄懂 i++++i Java中i++++i 想必大家都不陌生,但大多数同学对此可能都只是处于基础了解 @Test public void calculate(){ int i = 0; int m = i++; System.out.println(m);//输出0 int a = 0; int b = ++a; System.out.println(b);//输出1 }

HelloWorld 947

i++++i的区别

今天咱来聊聊关于 i++++i 到底有啥不一样哈! 相信这个问题绕晕了很多小白的脑瓜子!!!毕竟小编才接触这个的时候呢,也是脑瓜子嗡嗡嘚!!!! 首先++i与i++都是自加1 的意思哈!区别就在于先自加还是后自加! 别晕别晕哈!还没开始呢!!! 假设i=1;(方便后面友友的理解哈!) ++i 就是先自加1,再输出 (此处输出是指到达下一步前的值,并不是真正的输出哈!)那么此时执行++i...

naoguoteng的博客 1089

对i++++i的理解

有关自增自减运算在这里通过一个小程序来演示这两个运算的功能,自减运算i----i同理。 1、i++ 1 class Demo{ 2 public static void main(String[] args){ 3 int i=3; 4 5 System.out.println(i); 6 ...

denghan0583的博客 219

i++++i底层原理实现

1.1、i++ int i=0; for(int j=0;i<50;j++){ i=i++; } ------编译后指令------- //通过:javap 类名.class 反解析 iload_0 将局部变量表slot=0的变量(i),加载到操作数栈上 iinc 对局部变量表slot=0的变量(i)直接加1,但是操作数栈还是0 istore_o 将栈顶元素出栈赋值给局部变量表slot=0的变量。 //此时,局部变量i又被赋值为0 1.2、++i ii...

qq_37922915的博客 413

i++++i的区别(详细)?

i++++i的区别? public static void main(String[] args) { int i = 1; int j = 1; int a = i++; int b = ++j; System.out.println("a:"+a+","+"b:"+b);//a:1,b:2 System.out.println("i:"+i+","+"j:"+j);//i:2,j...

玻璃汽水的博客 672

Inter1-关于i++++i

Q:关于i++++i计算以下公式的结果 ```public static void main(String[] args) { int i = 1; System.out.println("i+++i++: " + (i+++i++)); System.out.println("i: " + (i)); System.out.println("i+++++i: " + ...

weixin_30326741的博客 199

i++ ++i 的区别

例如:① a = i ++ ② a = ++ i ①先赋值,再运算。即:a = i ; i = i + 1 ②先运算,在赋值。即:i = i + 1 ; a = i int i = 10; int x = ++i; // 这里的运算使得 i 的值发生改变。 System.out.println("x的值:" + x + " i的值:" + i); ...

@Fonden 2204

大数据与网络舆情分析-大数据与网络舆情分析.pptx

大数据与网络舆情分析-大数据与网络舆情分析.pptx

sac安装包linux及windows操作说明

sac安装包linux及windows操作说明

上一篇: String和char[]类型间的相互转化
下一篇: a=a+b和a+=b有什么不同?
wangqiuyue---
博客等级 码龄10年 31粉丝 62原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值