java局部变量 int a =1是存放在哪里

1.基本类型的 变量 a 和他所指向的值 1是存在栈里还是方法区的常量池中。
2.a中存的是1的值还是地址?

9个回答

说来惭愧,竟然都有些模糊了,一个方法中的变量名和变量值(这是两个概念)一般都是存在方法栈的本地变量数组中,有一种情况就是当变量的值为-128~127时,变量的值不会新建内存而是直接引用方法区常量池中的值。
所以你上面的第一个问题是,a这个变量名在栈的本地变量数组中,1这个值是直接引用方法区常量池中的值
第二个问题是,a中存的是1这个字面值,因为执行了int a = 1这个赋值操作

flonny
精锐小菜鸡 回复u011059021: 还有一点,一个线程中每次调用一个方法就有一个栈帧,而每个栈帧中也有不同的区域,我之前说a这个变量和压入的字面值都放在栈的本地变量数组中是不对的,a这个变量是放在本地变量数组中的,而压入的字面值是在操作数栈中的,可以参考博文:https://blog.csdn.net/zhoudaxia/article/details/26454421/
一年多之前 回复
flonny
精锐小菜鸡 回复u011059021: 纠正一下 1:istore_1这个操作其实就是赋值操作,是把上一步压入的字面值存到1这个标号中,而1标号指向的是a这个空间,具体你可以自己去javap反编译一下
一年多之前 回复
u011059021
KK_在努力 回复flonny: 谢谢。采纳你的回答。没想到一个简单的问题,多年的老程序员们居然回答的还不一致。
一年多之前 回复
flonny
精锐小菜鸡 回复u011059021: 然后回答你的问题,不管用的字面值是否在常量池中有存在,都存在入栈操作,然后在赋值,也就是说栈中必须有一块区域存放字面值,还有a这个空间,a经过赋值操作后存放的就是字面值本身。其java的汇编代码是:0: iconst_1(压入1常量)、 1: istore_1(存放a变量到1,1只是一个标号,不需要在意)
一年多之前 回复
flonny
精锐小菜鸡 回复u011059021: 我刚刚去看了一下jdk1.8的汇编,发现之前说的整数常量范围在栈操作中不是-128~127,因为压栈操作中的int类型常量入栈只有0~5,具体可以参考https://blog.csdn.net/lisulong1/article/details/53001211
一年多之前 回复
u011059021
KK_在努力 回复flonny: 如果是129,那么在栈里先存储a这个变量名,然后再存储一个129。最后赋值是把129放到a的空间,还是放129的地址?
一年多之前 回复
flonny
精锐小菜鸡 回复u011059021: 等于右边的1也是需要占用空间的,a中存的1这个值是在赋值操作之后才有的,那么1是怎么来的,是从常量池中拿出来赋值给a这个变量的,如果赋值的不是1而是-128~127以外的整数,那么jvm会在栈的本地变量数组中创建一个内存空间存放这个字面值,然后在进行赋值操作,通俗讲等于号左边的变量名和等于号右边的字面值是两个东西,都是需要有地方存储的
一年多之前 回复
u011059021
KK_在努力 这不是矛盾了吗?你都说了a中存的是1的值,然后上面又说是直接引用常量池中的值
一年多之前 回复

栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。)

这个问题我想再补充下。
lz陷入一种悖论中。因为不知道,所以要提问,然后面对各种矛盾的回答,你不知道相信谁。最后,你还是不知道。
这种情况下,lz无非两个选择:
(1)采用“投票”的方式,看哪种说法的回答多,就相信谁。
大部分的人为什么永远没有办法进步就是在于此,一方面他想从菜鸟的群体中脱离出来,另一方面他只接受菜鸟中大多数人的意见。并且顽固地认为这才是正确的认知方式。
(2)加上自己的思考、判断和求证。
求证的方式很简单,只要按照你的要求写个程序,反编译下java字节码,然后你就看到结论了。这是解决问题的终极方式。这个问题可以这么解决。
思考和判断是更进阶的方式。
可以教你一个简单的思想方法,我们把它叫做"奥卡姆剃刀原理"。简单来说就是八个字,如无必要,勿增实体。如果有两个理论都可以解释同一个事物,那么简单的那个取胜。
运用这个原理,你可以把自己想象成java语言的发明者和jvm的设计者。然后倒推这个问题。
为什么java要分为什么常量、简单类型、引用类型等等,显然java并非是为了考试和刁难它的使用者而徒增这些概念的。唯一的动机就是增加复杂性换取性能。那么如果不换取性能,最简单的方式是什么呢,显然就是一切变量都是引用类型,这是最简单的。一个引用类型可以概括java里所有的东西。
那么简单类型和常量是什么,它是特例。用特例换取性能。对于整数来说,它频繁参与到计算中,如果用定义一个类,并且使用一个指针的方式来使用它,就会浪费很多性能。所以才有了简单类型。而常量是怎么回事?它是对大量重复使用的引用类型的一种性能优化,用共享对象的方式,来将大量相同的对象合并存储唯一的一份。搞清楚了这些,再回过头来看你的问题,就很简单了。

zhuanpenglve0711
木心__ 听君一席话,胜读十年书。
大约一年之前 回复
flonny
精锐小菜鸡 我是站在你这队的,只是解释为什么是这样的结果o.o
一年多之前 回复

如果是写在函数里的,那么a放在堆栈上。存储的就是值。
Integer(1)放在常量池中

caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复u011059021: 是的。
一年多之前 回复
u011059021
KK_在努力 回复caozhy: 回到问题本身,存在栈中,栈中a应该存的是值1本身。把分给你吧
一年多之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 我刚学编程的时候,用的是和apple ii兼容的中华学习机,rom basic,后来用了pc,gw-basic。这两种语言都不支持堆栈,虽然gwbasic已经有了go sub这样的语句。
一年多之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复u011059021: 那个时候java还没有呢。java 1995年才有的吧。
一年多之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复u011059021: 就是叫堆栈,我上小学的时候就是这么叫了。(大概1990年代)
一年多之前 回复
u011059021
KK_在努力 回复caozhy: 不是,堆栈我觉得是说堆或者栈
一年多之前 回复
u011059021
KK_在努力 回复caozhy: 堆栈是<编程思想>的中文版里翻译的吧,其他地方都是栈吧
一年多之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复u011059021: 你是不是认为堆栈是指堆上的栈?而引起误会。好比老师必须要说师,否则会理解为年老的老师?哈哈。堆栈就是一个固定的名词。
一年多之前 回复
flonny
精锐小菜鸡 回复u011059021: 他说的没错,stack可以叫栈也可以叫堆栈,你可以百度一下
一年多之前 回复
u011059021
KK_在努力 回复caozhy: 我的意思是 stack指的是栈,heap值得是是堆。就像说 teacher(老师)一样
一年多之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复u011059021: stack就是堆栈,不存在“stack栈”,好比heap就是堆,不能说heap堆。
一年多之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复u011059021: 你的问题我已经回答了,既然是基本类型,就没有“指向的值”一说,只有对象引用才有。
一年多之前 回复
u011059021
KK_在努力 回复caozhy: 你说的我知道,我问的是题目上的情况。并且最好不要说堆栈(应该是想说stack栈吧),以免误导。
一年多之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复u011059021: 对。Person p = new Person(); // p是一个引用,在堆栈上,指向的对象(new Person)在堆上。
一年多之前 回复
u011059021
KK_在努力 new出来的对象应该放在堆中吧
一年多之前 回复

首先明确a是int类型,基本类型,所以问题2的答案很明显,a中存的是1的值,因为是局部变量,所以是在a和1均在方法区中

u011059021
KK_在努力 你在瞎说。局部变量存在栈中。类中常量和静态变量等放在常量池中。第二个问题也不对
一年多之前 回复

1.a是变量,所以方法执行的时候a和它的值在栈中,方法执行完后a就销毁了
2.a中存的是1的值。

局部变量存在栈中。类中常量和静态变量等放在常量池中。

楼主弄明白了嘛 最近复习的时候也遇到了这个问题 现在的理解是 int a 这个a变量存在栈中 但是这个代表值的1不知道是怎么算的 假如有个int b =1 那这俩个1在实际内存中的地址不知道是不是一致的 望解答

问题二 a存的值是1,但他的内存地址指向常量池1,

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!