局部变量声明而不赋值,和赋值为null,在内存分配上有什么区别?

bigbro001 2011-12-04 11:14:28
在主方法中声明

String str;
栈内存中会开辟一块空间用来保存引用str

String str = null;
这句话同上,只会在内存的栈中开辟一块空间保存String引用str,并没有在堆中建立任何对象,或者令引用str指向堆中的某个位置

可是,为什么再后面的代码中,如果需要使用str的时候,第一句话会报错(未被初始化),第二句话却不会报错呢?
难道说,令str=null;意味着str会指向堆内存中的某个位置?
...全文
2343 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
bigbro001 2013-03-25
  • 打赏
  • 举报
回复
恳请各位前辈提供思路。。。
老紫竹 2012-09-10
  • 打赏
  • 举报
回复 2
给你块地,地里现在有啥谁都不知道。
给你块地,同时把地清空了,啥都没有了。
bigbro001 2012-09-10
  • 打赏
  • 举报
回复
不知ZangXT大侠,火龙果,老紫竹等前辈有什么高见。。。
bigbro001 2012-06-08
  • 打赏
  • 举报
回复
来个总结吧:

int test(){
String str = null;
str = "String";
}
像这种String str = xxx;
不管xxx是null还是其他字符串,str这个东西都是在栈里有块空间,可以理解为c的指针,=null的时候,里面存的是0,非null的时候存的是实际字符串的地址(堆中或者常量池中)。

而String str;
这种情况,jvm同样也为其分配了一块空间,但是不知道值是多少
java语法要求引用之前必须初始化,所以你直接这么写,str根本不能引用,所以无所谓。
其实jvm也完全可以不为它分配空间。

这个问题,说到底,其实就是java的语法要求,必须初始化的问题。

如果有C语言经验的话,可能有这样的问题,
int i;
int j = i; //使用了未初始化的i
因为i没有初始化,所以i是个“随机的值”,比如i可能是5,可能是8,可能是……
java为了避免这种问题,语法上规定,局部变量在使用之前,必须初始化!如果不初始化就报错。
AngelWings 2012-06-05
  • 打赏
  • 举报
回复
赋值为null的最后都会被JVM回收机制所回收,并不会去占用内存!
dracularking 2012-06-05
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 的回复:]

恩。。。俺的意思是,
String str = null;
str = "String";
最后的"String"对象是建立在栈里的,而不是堆里的,这样一来,第一句话,仍然还是在堆中开辟空间么?因为最后的对象其实是在栈中,如果一开始声明null的时候,在堆中开辟空间,岂不是有点奇怪?
[/Quote]
1. null不是一个对象,JLS 3.10.7 中提及的是The Null Literal,况且它是ASCII中值为0的一个字符
2. null instanceof Object 是false 也证明了它不是Object
3. null在JVM全局内存中只存在一个,因为它无需存在多个,造成不必要浪费,因此挺符合String interned的初衷。All literal strings and string-valued constant expressions are interned. 我觉得null勉强能算是literal string,因为它是基于字符的。

综上,既不是Object又够格interned,所以认为null是在栈中开辟。
buliar 2012-06-05
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 的回复:]

敢问楼上的大侠,如果是:
String str = null;
str = "String";

这种情况,第一句话还是在堆内存中开辟空间吗?
[/Quote]

String这种可以当做基本类型类使用的特殊关键字。不太适合来研究对象。个人见解。
fangjinsong 2012-06-05
  • 打赏
  • 举报
回复
我还是不懂啊,没有一个专业的内存解释。
古布 2012-06-05
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 的回复:]
恩。。。俺的意思是,
String str = null;
str = "String";
最后的"String"对象是建立在栈里的,而不是堆里的,这样一来,第一句话,仍然还是在堆中开辟空间么?因为最后的对象其实是在栈中,如果一开始声明null的时候,在堆中开辟空间,岂不是有点奇怪?
[/Quote]
看看下面的字节码,LZ就明白了

Code:
0: aconst_null
1: astore_1
2: ldc #19; //String String
4: astore_1
5: return

LineNumberTable:
line 12: 0
line 13: 2
line 16: 5

LocalVariableTable:
Start Length Slot Name Signature
0 6 0 args [Ljava/lang/String;
2 4 1 str Ljava/lang/String;

bigbro001 2011-12-18
  • 打赏
  • 举报
回复
终于再次看到久违的火龙果大侠了。。。3年前还是3星,现在变成了5星。。。另一个厉害人物ZangXT貌似很久没来过了。。。
  • 打赏
  • 举报
回复
我感觉看过 Thinking in Java 的人就喜欢研究这种问题!
bigbro001 2011-12-18
  • 打赏
  • 举报
回复
肯请各位热心前辈分享?
戏子 2011-12-07
  • 打赏
  • 举报
回复
打个比方
String str;就像你准备生产一个盒子,在盒子生产出来之前你给它了名字叫str,但盒子到底是什么却没有实体
而String str=null;就像你已经生产了盒子,给这个盒子起名叫str
换做内存就是:String str;就是给出了堆栈空间的名字,却没有给出堆栈的实际空间
而String str=null,就是给出了堆栈的空间名字,并且给出了堆栈的空间,虽然这个空间什么都没有

----初学者的一点浅薄理解,有不对的地方请大侠指正
bigbro001 2011-12-07
  • 打赏
  • 举报
回复
恩。。。俺的意思是,
String str = null;
str = "String";
最后的"String"对象是建立在栈里的,而不是堆里的,这样一来,第一句话,仍然还是在堆中开辟空间么?因为最后的对象其实是在栈中,如果一开始声明null的时候,在堆中开辟空间,岂不是有点奇怪?
戏子 2011-12-07
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 bigbro001 的回复:]

敢问楼上的大侠,如果是:
String str = null;
str = "String";

这种情况,第一句话还是在堆内存中开辟空间吗?
[/Quote]

应该是开辟的,null 和 什么都不写是有区别的
你可以理解:一个平台,String str;表示平台上什么都没有,及没有开辟空间,String str=null;表示平台上有一个空箱子,虽然箱子里什么都没有,但仍然是开辟了空间的
bigbro001 2011-12-07
  • 打赏
  • 举报
回复
敢问楼上的大侠,如果是:
String str = null;
str = "String";

这种情况,第一句话还是在堆内存中开辟空间吗?
潇水汀寒 2011-12-07
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 bigbro001 的回复:]
多谢各位的热心分享,试着总结:
2) String str = null;
栈内存开辟一块空间,储存str引用,
栈内存中(或者堆内存中?)开辟一块空间,
str指向那块空的内存的地址
3)String str = new String("String");
栈内存开辟一块空间,储存str引用,
堆内存……
[/Quote]
2)是在堆内存中
3)String str = new String("hello"); 先在内存的常量池中查询是否存在“hello”,如存在,则将该块空间复制一份到内存的堆区间上,并将str指向该块区域,如不存在,则先在常量池中创建 一个“hello”,然后将其复制到堆,再令str指向它。就是说无论如何都必然会创建一个新的Hello字符串对象,不管你字符串池有没有

结贴 啦啦啦~~~ 其实我也不懂 抄来的 呼呼
bigbro001 2011-12-07
  • 打赏
  • 举报
回复
多谢各位的热心分享,试着总结:

1) String str;
栈内存开辟一块空间,存储str引用

2) String str = null;
栈内存开辟一块空间,储存str引用,
栈内存中(或者堆内存中?)开辟一块空间,
str指向那块空的内存的地址

3)String str = new String("String");
栈内存开辟一块空间,储存str引用,
堆内存中开辟一块空间,储存新建的String对象“String”,
str指向堆内存中新String对象的地址
pengkangde 2011-12-07
  • 打赏
  • 举报
回复
学到了 谢谢各位大虾 楼主给分
bigbro001 2011-12-06
  • 打赏
  • 举报
回复
多谢楼上各位前辈的热心解答,还是JavaSE版人气高啊。。。可惜老紫竹,ZangXT大侠,火龙果,猴子等前辈不见了。。。
加载更多回复(15)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧