一段java代码的一些思索

来源:互联网 发布:印度人眼中的中国知乎 编辑:程序博客网 时间:2024/05/16 18:16

int i=1;
  int i2=3;
  System.err.println("i "+i+"][ i2 "+i2);

i=i2+0*(i2=i);    //①

  System.err.println("i "+i+"][ i2 "+i2);

i=3; i2 =1

 

今天某群看见这么一段代码,结果大致可以理解。

 

先看下①这一句    i=i2+0*(i2=i);   //①

 

  public static void main(java.lang.String[]);

    Code:

       0: iconst_1   //1

       1: istore_1   //赋值 I=1

       2: iconst_3   //3

       3: istore_2   //赋值 i2 =3

       4: iload_2    //将i2加载到栈

       5: iconst_0    //将0加载到栈

       6: iload_1 //将i加载到栈

       7: dup //复制栈顶数值(数值不能是long或double类型的)并将复制值压入栈顶       8: istore_2   //将复制的值保存到i2

       9: imul       //做乘法 0

      10: iadd       //做加法 i2+0

11: istore_1 

//将值存入i = i2+0,[此处的i2是先前变换之前存进去的,所以还是原来的值

      12: return

}

按照这个顺序,结果讲的通。但是想了一想,这里的int是基本数据类型,而且是32位直接传值。如果是换成传引用,那么i2应该就不是原来的值了吧?于是想着用Integer进行操作,传引用进去。

 

Integer i1 = new Integer(1);

     Integer i2 = new  Integer(2);

     i1 = i2+0*(i2=i1);

 

Code:

       0: new           #2                  // class java/lang/Integer

       3: dup

       4: iconst_1

       5: invokespecial #3                  // Method java/lang/Integer."<init>":(I)V

       8: astore_1

       9: new           #2                  // class java/lang/Integer

      12: dup

      13: iconst_2

      14: invokespecial #3                

 // Methodjava/lang/Integer."<init>":(I)V调用构造方法

      17: astore_2

      18: aload_2

      19: invokevirtual #4                

 // Method java/lang/Integer.intValue:()I调用实例方法

      22: iconst_0

      23: aload_1

      24: dup

      25: astore_2

      26: invokevirtual #4                 

//Method java/lang/Integer.intValue:()I调用实例方法

      29: imul

      30: iadd

      31: invokestatic  #5                 

//Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 调用静态方法

      34: astore_1

      35: return

int java.lang.Integer.intValue()

Returns the value ofthis Integer as anint.

publicintintValue() {

        returnvalue;

    }

 

Integerjava.lang.Integer.valueOf(int i)

 

Returns an Integer instance representing the specifiedint value. If a newInteger instance is not required, this method should generallybe used in preference to the constructorInteger(int), as this method is likely to yieldsignificantly better space and time performance by caching frequently requestedvalues. This method will always cache values in the range -128 to 127,inclusive, and may cache other values outside of this range

publicstaticInteger valueOf(inti) {

        assert IntegerCache.high >= 127;

        if (i >= IntegerCache.low && i<= IntegerCache.high)

            return IntegerCache.cache[i + (-IntegerCache.low)];

        returnnew Integer(i);

    }

 

 

 

由这些代码猜测,可能Integer的算数运算还是使用的Integer的值(int),可能与直接用int无异。

Java本来就不支持对象的算数运算,Integer对象之所以能计算,可能是编译器做了处理,1.4版本往前的都不支持Integer i =1 ;这样的赋值。Java不支持对+-*/运算符的重载。想了想,用64位的基本类型进行操作,想了想虚拟机应该是支持64位的值操作。想不到如何计算对象了T_T。

后来又想到了一个, I =i2的旧值,因为i2的新值和栈值不在一个地方。那么有个volatile关键词可以使得i2可见,然后试了试结果还是i2用的是原来的值。

Code:

       0: getstatic     #2                  // Field i2:I

       3: iconst_0

       4: getstatic     #3                  // Field i1:I

       7: dup

       8: putstatic     #2                  // Field i2:I

      11: imul

      12: iadd

      13: putstatic     #3                  // Field i1:I

      16: return

 

Why?????

 

是不是putstatic还没有将volatile i2 的值同步回主内存,后续的计算就结束了呢???还是同一个线程中volatile没什么作用呢?这里理解不了!

另外这样写,显式的调用iload获取新值。

inti1 =1;

         inti2 =2;

         inti3 = 0*(i2=i1);

         i1 =i2 +i3;

i1 =1 ,i2 =1

这样应该是

0:iconst_1

       1: istore_1

       2: iconst_3

       3: istore_2

       4: iconst_0

       5: iload_1

       6: dup

       7: istore_2

       8: imul

       9: istore_3

      10: iload_2   //这里重新加载了i2变量,所以是新值了?

      11: iload_3

      12: iadd

      13: istore_1

      14: return

 

这样理解不知道对不对,有待继续学习然后解释。

妄高手不吝赐教~



150925更新:

又看了一下volatile关键字:当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。

就是工作空间中的volatile变量被更新后会立即更新到主内存,但是之前已经读取的值(已经存入工作空间的)不会被更新,除非进行新一次的读取。

而普通的变量,在工作空间中被更改以后什么时候被更新回主内存,这个时间是不确定的。





0 0