日期:2014-05-20  浏览次数:20644 次

小弟出到贵宝地,特有一事不明,还望居士们不吝赐教一二,弟不胜感激呼!
事情经过是这样的:
int a=3; 就当局部变量好了

我一直没搞明白的是,a变量在编译器编译之后 其实就是一个地址了。比如0x00001

那把数值3赋值给a,其实就是给地址0x00001里写入数值3是吗?

那我可以这么理解吗 编译后的文件 数据其实都是在硬盘里躺着的,还没有运行,那么在硬盘里的数据是一个什么情况的状态?是不是变量a已经变成地址0x00001  数值3变成二进制11

然后当程序运行时,就把数值11写入到0x00001里面去了?

但是我还有个疑问 数值3本身还有一个自己的空间吗?比如它自己还有一个地址空间是0x00002 然后先把3写到它自己的地址里,然后0x00001在指向0x00002的地址? 如果是这样的话,那请问0x00001里面装的是地址0x00002这个地址还是0x00002里面的值11? 还是说根本就没0x00002这个地址,直接把11就写入到0x00001里就OK了?
那其实编译后的文件里 其实里面格式应该是这样 0x00001=11; 我觉着要是这样就简单多了

但是说这时候有个int b=3 b也指向3 可以共享数值3的,那这么说的话 b和a 都应该指向数值3,那到底3有没有地址来保存它呢?

要是没地址,赋值给0x00001后就没有了啊,那b上哪指向数值3去哦,难不成b指向0x00001地址获取数值?

所以我晕了,常数到底编译时候 给不给地址啊 还是等程序运行时候加载时候 内存才分配地址?不应该是这样 要是分配也应该是编译的时候就应该给分配地址才对

所以我晕了,求大神们指点下我这个迷糊的羔羊吧。。。。

------解决方案--------------------
假设代码如下:
public class A{
  int a=3;
}
java加载A时,会解析A类的代码,寻找其中的常量,也就是不会在变的量。
如:
3 ,  9.9 ,  “test”
然后在加载时,会在java的一个叫常量池的地方去寻找有没有3这个常量。如果没有,就在常量池中建一个3,也就是在内存中某个位置赋值11.

当java初始化A时,执行int a=3;
首先,在栈中开辟一个空间作为a,然后从常量池中取得3的内存地址,将这个地址赋给a.

换句话说,a里面存的是地址,而不是值。
这也是为什么你
int b=3;
a和b能相等的原因。

理由:

int a=1;
int b=a;
a=2;
System.out.println(b);

print:1
如果b只是简单的指向a的话,a的值改变,b也会变的,但是结果b没变。就是因为刚开始a和b都指向常量池中1的地址值。然后a指向了2的地址值。但是b指向的地址值并没有变。

当然,如果楼主理解的更加细致的话,就需要看看JVM的工作原理了。