首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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

由于i++和i--的使用会导致值的改变,所以在处理后置的++和--的时候,java的编译器会重新为变量分配一块新的内存空间,用来存放原来的值, 而完成赋值运算之后,这块内存会被释放。...(1)对于j = i++的情况 ?   ...i的原始值存放在后开辟的内存中,最后将这个值赋给j,进行j = i++运算之后,j会得到i的值,而i又将自加,所以,在释放内存之后,原来存放j和i的地方将得到的值分别是:j(此时的值等于初始i的值)和i...每一次的循环结束,用来保存i的原始值的内存的数据会被销毁,然后i的新的值又会被放在一段新的内存中,在进行上述的循环,所以最终能够实现j的数据的增加。 (2)对于i = i++的情况 ?...总结:  Java编译器每次遇到自增(指的是i++)、自减(指的是i--)运算符的时候都会开辟一块新的内存空间来保存赋值之前j的值,即为缓存变量,然后再将这个换成变量的值赋给左边的变量。

1.4K100
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    java中i++ 和 ++i的区别

    今天同事扔给我两道面试题,由于我2年前就接触过这道题,所以没啥意思,我看完后扔到一个交流群里,回答这道题的绝大部分人竟然都答错了;很多人很清晰的知道这两道题想考察面试者对 i++ 和 ++i 的理解...,也很清晰的知道这二者的区别,但是题还是做不对;两道题如下,大家可以先思考一下,给个答案,然后再去验证自己的想法。...(这是一道典型的看着非常简单的题,但是不少人还是会因为粗心栽跟头) 第一题: int a = 0; for (int i = 0; i i++) {...(int i = 0; i i++) { b = ++ b; } System.out.println(b); 我估计会有不少人做错...i++ 和 ++i 在理论上的区别是: i++:是先把i拿出来使用,然后再+1; ++i :是先把i+1,然后再拿出来使用; 答案见下: 第一题:a=0 第二题:b=99 再升级一下 第三题

    1.2K30

    从volatile说到i++的线程安全问题

    ,当然使用volatile的同时也会增加性能开销 注意 volatile并不能保证非源自性操作的多线程安全问题得到解决,volatile解决的是多线程间共享变量的「可见性」问题,而例如多线程的i++,+...+i,依然还是会存在多线程问题,它是无法解决了.如下:使用一个线程i++,另一个i--,最终得到的结果不为0 public class VolatileTest { private static...,我们若查看字节码,会发现 void f1() { i++; } 的字节码如下 void f1(); Code: 0: aload_0 1: dup 2: getfield #2; //Field i...:I 5: iconst_1 6: iadd 7: putfield #2; //Field i:I 10: return 可见i++执行了多部操作, 从变量i中读取读取i的值 -> 值+1 -> 将...使用volatile会增加性能开销 volatile并不能解决线程同步问题 解决i++或者++i这样的线程同步问题需要使用synchronized或者AtomicXX系列的包装类,同时也会增加性能开销

    43020

    关于 i=i++; 出乎意外的结果

    今天和大家分享一道题 var i = 0; var a = i++; console.log(a); 答案,相信大家一眼就能看出, 结果为 0 下面变化一下,代码如下 var i = 0; i =...i++; console.log(i); 结果多少呢?...简单翻译: 如果该运算符作为后置操作符,则返回它递增之前的值;如果该运算符作为前置操作符,则返回它递增之后的值 所以,我们就知道, ++运算符会返回一个值,如果前置,则返回操作对象递增之后的值,如果后置...当 var i=0 ; var i = i++; 时,实际上做了如下操作 i = 0 j = i; // j 操作运算时系统生成的 i = i+1; i = j; // 故i=0 当 var...;++运算符的优先级都高于=号; 区别在于,++返回的是递增之前的值,还是递增之后的值

    73320

    【答疑解惑】i++,++i,i+=的区别

    说起这个i++, ++i 入门练习都会搞这个,一如既往,百试不爽。...表达式 a = i++; 它等价于 a = i ; i = i + 1; 表达式 a = ++i 它等价于 i = i + 1; a = i; 1、 首先两者的区别是:前者是先赋值,然后再自增;...后者是先自增,后赋值 2、 ++i 和i++ 的使用,一般来说在循环域里面,这两者并没有什么很大的区别,因为编译器一般都会给你做优化。...但是要注意其生存周期,我们要注意i值在程序流中的变化,如果是for、while循环判断中要特别注意++i的值比i++值要提前。...没有结果,因为不同的编译器做出来的结果,你要纠结这个,哎我只能说那些书上纯粹是搞人。 以上我们只需记住先序后续递增,循环判断时的条件即可。

    1.8K50

    短文:用字节码解析i++和++i的区别

    记得刚工作的时候被问i++是不是原子操作。初出茅庐答不上来,对java并发不了解。以此笔记缅怀自己的年轻。...是不是很无聊,相信很多人会回答,i++是先赋值再+1,++i是先+1再赋值。确实是这样,但是我总是想追根溯源,如何解释这个原则? 打开IDEA,下载一个jclasslib插件。 ?...右边就是显示这个类的class字节码信息,字节码其实是一堆二进制数据,当然,这些二进制数据按一定的规则存放,这个插件就是简单根据规则翻译了这个class文件,我们先看i=i++。.../System.out> 11 iload_1 12 invokevirtual #3 15 return 关于i++,和++i的字节码指令JVM...从表面上看就是上文说的,i=i++先赋值再加1,i=++i先加1再赋值。 曾经的那个面试官,你在哪儿,我来回答你当年那个问题,可能你并不知道也停留在表面吧。

    82520

    面试题:对$i++和for循环的考察

    $i = 1; for(i=0; i<10; } echo $i; 解析:这道题其实主要是考察我们对$i++和for循环的理解,可以说是对基础掌握的了解。...首先看看 i++和 ++i的基本区别: i++ : 先在表达式中使用 i的值然后在加 1 。 ++i : 先使用i的值加1后,然后在在表达式中使用新的值。...下面举例说明一下: 1、i++ 的用法(以 a=i++, i=2 为例 ) 先将i的值赋值给变量a(也就是 a=i),然后i的值在加1 (也就是i = 则最终 $a 的值等于2,i 值等于3。...所以a=i++ 相当于a=i,i = i+1; 2、++i 的用法(以a=++i,i=2为例) 先将i的值加1(也就是 i=i+1),然后赋值给a(也就是a=i)。 则最终i=3,a=3。...是不是上面的题目有了答案,其实最开始的$i=1是迷惑我们的,和整体没啥关系。

    90120

    为什么说 ++i 的效率比 i++ 高?

    ++i与i++的区别 这两个表达式从我们初学编程语言的时候就会接触到。前者是自增后取值,后者是取值后自增。 ? 运行结果: ? 对于这个结果我们并不感到意外。...另外我们还注意到另外一个有意思的现象: ? 编译后报错: ? 说&作用于左值,也就是说a++的结果并非左值。但++b的结果是左值。...仔细观察后,我们发现前置自增,先自增,后返回原对象的对象;没有产生任何临时对象;而后置自增,先保存原对象,然后自增,最后返回该原临时对象,那么它就需要创建和销毁,这样一来,效率孰高孰低就很清楚了。...在不进行赋值的情况下,内置类型前置和后置自增的汇编都是一样的呢! ? 汇编: ? 不过,赋值的情况下,并且不开启编译器优化,它们的汇编代码还是有差别的,有兴趣的可以试试。...总结 对于内置类型,前置和后置自增或者自减在编译器优化的情况下,两者并无多大差别,而对于自定义类型,如无特别需要,人们似乎更加偏爱前置自增或自减,因为后置自增常常会产生临时对象。

    66330

    从volatile说到i++的线程安全问题

    ,当然使用volatile的同时也会增加性能开销 注意 volatile并不能保证非源自性操作的多线程安全问题得到解决,volatile解决的是多线程间共享变量的「可见性」问题,而例如多线程的i++,+...+i,依然还是会存在多线程问题,它是无法解决了.如下:使用一个线程i++,另一个i--,最终得到的结果不为0 public class VolatileTest { private static...,我们若查看字节码,会发现 void f1() { i++; } 的字节码如下 void f1(); Code: 0: aload_0 1: dup 2: getfield #2; //Field i:...I 5: iconst_1 6: iadd 7: putfield #2; //Field i:I 10: return 可见i++执行了多部操作, 从变量i中读取读取i的值 -> 值+1 -> 将+1...使用volatile会增加性能开销 volatile并不能解决线程同步问题 解决i++或者++i这样的线程同步问题需要使用synchronized或者AtomicXX系列的包装类,同时也会增加性能开销

    1.2K30

    从volatile说到i++的线程安全问题

    注意 volatile并不能保证非源自性操作的多线程安全问题得到解决,volatile解决的是多线程间共享变量的可见性问题,而例如多线程的i++,++i,依然还是会存在多线程问题,它是无法解决了.如下:...使用一个线程i++,另一个i--,最终得到的结果不为0。...+i并非原子操作,我们若查看字节码,会发现: void f1() { i++; } 的字节码如下: void f1(); Code: 0: aload_0 1: dup 2: getfield #2;...//Field i:I 5: iconst_1 6: iadd 7: putfield #2; //Field i:I 10: return 可见i++执行了多部操作, 从变量i中读取读取i的值 ->...使用volatile会增加性能开销 volatile并不能解决线程同步问题 解决i++或者++i这样的线程同步问题需要使用synchronized或者AtomicXX系列的包装类,同时也会增加性能开销

    30520

    图解 i++ 和 ++i 的区别!看了必懂

    先看一段代码: int i = 0; int a = i++; sout("a的值是:"+i); sout("i的值是:"+i); 最终的编译之后的核心字节码如下 L0 BITPUSH 0 //将常量...ISTORE_2 弹出的栈顶元素值依旧是0,并未改变 最终的输出的结果为: a的值是: 0 i的值是: 1; 我这里画了一个图来帮助大家理解 再来看看++i int i = 0; int a = ++...i; sout("a的值是:"+i); sout("i的值是:"+i); 对于++i 来说,对应的字节码如下,先自增再入栈,那么结果就很清晰了 最终的核心编译之后的字节码如下 L0 BITPUSH 0...//从局部变量表的第二个slot槽中,取出该值,压入操作栈顶 IRETURN //返回栈顶元素 最终的输出的结果为: a的值是: 1 i的值是: 1; 总结 i++ 和 ++i 在理论上的区别是...: i++:是先把i拿出来使用,然后再+1; ++i :是先把i+1,然后再拿出来使用;

    43220

    快看,i++真的不安全

    上期文章讲到“i++;”本身是一个线程不安全的操作,原因是操作不是原子性的,存在取值和赋值的两个过程,但是究竟怎么会不安全呢?本期借助一个“vmlens”的项目来演示为何会发生线程不安全的情况。...: public class TestCounter { private volatile int i = 0; @Interleave public void increment() { i+...从图中我们可以看出在两个线程同时执行“i++;”的时候,两个线程都先后读取到了i的值“0”,然后先后完成了计算“i+1”,最后又先后给i赋值“1”,导致测试用例执行失败。...---- 介绍一下这个插件: “vmlens”是一款测试java多线程的工具。 1. 需要测试多个线程访问相同内存位置或监视器的应用程序的所有部分。...这与数据竞争和死锁的自动检测一起导致系统和可重复的测试。 3. 通过查看多个线程以何种方式访问相同状态,您可以减少共享状态的数量。 4. 较少共享状态意味着需要较少的同步监视器。

    40930

    字节跳动面试官:i++ 是线程安全的吗?

    ,当然使用volatile的同时也会增加性能开销 注意 volatile并不能保证非源自性操作的多线程安全问题得到解决,volatile解决的是多线程间共享变量的可见性问题,而例如多线程的i++,++i...,依然还是会存在多线程问题,它是无法解决了.如下:使用一个线程i++,另一个i--,最终得到的结果不为0 public class VolatileTest { private static...+和++i并非原子操作,我们若查看字节码,会发现 void f1() { i++; } 的字节码如下 void f1(); Code: 0: aload_0 1: dup 2: getfield #2...; //Field i:I 5: iconst_1 6: iadd 7: putfield #2; //Field i:I 10: return 可见i++执行了多部操作, 从变量i中读取读取i的值...使用volatile会增加性能开销 volatile并不能解决线程同步问题 解决i++或者++i这样的线程同步问题需要使用synchronized或者AtomicXX系列的包装类,同时也会增加性能开销

    47620

    从JVM层面来解释i++和++i的真正区别

    前言 如果只用普通的知识解释i++和++i的话 i++ 先将i赋值再++ ++i 先++再赋值 但是这简单的回答并不能入吸引面试官的眼球,如果用java字节码指令分析则效果完全不同。...代码实现 public class OperandStackTest { /** 程序员面试过程中, 常见的i++和++i 的区别 */ public static void...先将i1的值为10入栈(bipush),然后将int类型的值从栈中存到局部变量表0的位置,然后执行iinc将0位置的值+1,然后将局部变量表0位置的数入栈执行输出操作 所以i1的值为11 先将i2的值为...10入栈(bipush),然后将int类型的值从栈中存到局部变量表1的位置,然后执行iinc将1位置的值+1,然后将局部变量表1位置的数入栈执行输出操作 所以i2的值为11 总结 由于没有赋值操作,区别不大...先将i9=10入栈,然后存在局部变量表8的位置 int i10 = i9++ + ++i9; 先iload将8位置的i9入栈然后执行iinc将8处的i9加一,然后执行++i9,在将8处的i9加一 此时

    40420
    领券