java常量的问题

movaxbxcxdx 2012-07-20 06:41:47
java中如果
public static void main(String args[])
{
int a=9;
}
在主函数中定义一个a这个a是存储在常量池中还是main函数的栈中?
我知道如果Integer a=9;的话肯定是在常量池中;
求明白的,解释一下;或者推荐一篇文章让我明白一下;
...全文
175 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
ZangXT 2012-07-21
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

Integer a=9;相当于Integer a=Integer.valueOf(9);
为什么不是Integer a=new Integer(9);??
[/Quote]
语法糖,为了避免每次都创建新的对象。
而且还是出于一个自然的考虑,如果Integer a = 9;Integer b = 9;
那么 a == b 就应该为true。所以设计了缓存策略。不过因为整数太多,全部缓存下来占内存太大了,所以只缓存了一些比较常用的,比如-128~+127(可调整)等。范围之外的其实还是通过new创建。
具体实现可以去看Integer类的代码。
zhangyong369 2012-07-21
  • 打赏
  • 举报
回复
Integer a=9;相当于Integer a=Integer.valueOf(9);
为什么不是Integer a=new Integer(9);??
ZangXT 2012-07-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

在一篇文章中说:常量池指的是在编译期被确定,并被保存在已编译的。class文件中的一些数据。除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值(final)还包含一些以文本形式出现的符号引用。详见:http://sd.csdn.net/a/20120629/2806999.html
这句话不是说常量池包含了各种基本类型?是不是原文有错误和疏漏呀……
[/Quote]
这个链接绝大多数信息是错误的。

class文件中是有常量池描述信息,但程序运行的时候会运行到内存。很多地方第一步就没有分清静态的信息(class文件中的信息)和动态的信息(内存)。
movaxbxcxdx 2012-07-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

引用 3 楼 的回复:
在一篇文章中说:常量池指的是在编译期被确定,并被保存在已编译的。class文件中的一些数据。除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值(final)还包含一些以文本形式出现的符号引用。详见:http://sd.csdn.net/a/20120629/2806999.html
这句话不是说常量池包含了各种基本类……
[/Quote]
受教了!看来得专心学一下jvm了
qybao 2012-07-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
在一篇文章中说:常量池指的是在编译期被确定,并被保存在已编译的。class文件中的一些数据。除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值(final)还包含一些以文本形式出现的符号引用。详见:http://sd.csdn.net/a/20120629/2806999.html
这句话不是说常量池包含了各种基本类型?是不是原文有错误和疏漏呀?……
[/Quote]

常量池是在编译期确定是没问题的,javap查看的就是编译好的class文件,并没有执行,所以常量池信息是编译在class文件里的,但是基本类型并不是任意一个就被编译为常量池的信息,另外,常量池信息除了保存一些常量外,还有一些符号引用信息。
qybao 2012-07-20
  • 打赏
  • 举报
回复
LS都说了,就补充说一说
基本类型是保存在栈里的
Integer a=9;相当于Integer a=Integer.valueOf(9); 当valueOf的参数在[-128,127]之间的时候,直接返回缓存区的Integer对象(IntegerCache的Integer数组元素),在这个过程中,常量池并没有保存任何Integer对象信息,不要被常量池误导,也不要以为常量池保存了Integer对象,基本类型就会指向常量池的对象,要知道基本类型不是引用(指针),只能保存值,并不保存对象地址

可以通过javap来查看常量池信息以及是否发生了常量池相关的指令

public class jp {
public static void main(String[] args) {
int i = 5;
int j = Short.MAX_VALUE;
int k = Short.MAX_VALUE + 1; //常量池
Integer n = 9;
String a = "abc"; //常量池
}
}


java jp.java //编译
javap -verbose jp //查看伪代码指令

E:\test>javap -verbose jp
Classfile /E:/test/jp.class
Last modified 2012-7-20; size 371 bytes
MD5 checksum 91b7fc961840dbb87aba229d7f51bf7f
Compiled from "jp.java"
public class jp
SourceFile: "jp.java"
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #6.#15 // java/lang/Object."<init>":()V
#2 = Integer 32768
#3 = Methodref #16.#17 // java/lang/Integer.valueOf:(I)Ljava
/lang/Integer;
#4 = String #18 // abc
#5 = Class #19 // jp
#6 = Class #20 // java/lang/Object
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 main
#12 = Utf8 ([Ljava/lang/String;)V
#13 = Utf8 SourceFile
#14 = Utf8 jp.java
#15 = NameAndType #7:#8 // "<init>":()V
#16 = Class #21 // java/lang/Integer
#17 = NameAndType #22:#23 // valueOf:(I)Ljava/lang/Integer;
#18 = Utf8 abc
#19 = Utf8 jp
#20 = Utf8 java/lang/Object
#21 = Utf8 java/lang/Integer
#22 = Utf8 valueOf
#23 = Utf8 (I)Ljava/lang/Integer;
{
public jp();
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>
":()V
4: return
LineNumberTable:
line 1: 0

public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=6, args_size=1
0: iconst_5
1: istore_1
2: sipush 32767
5: istore_2
6: ldc #2 // int 32768
8: istore_3
9: bipush 9
11: invokestatic #3 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
14: astore 4
16: ldc #4 // String abc
18: astore 5
20: return
LineNumberTable:
line 3: 0
line 4: 2
line 5: 6
line 6: 9
line 7: 16
line 8: 20
}

红色是常量池信息,蓝色是跟常量池发生关系的指令
可以,整形和String不一样,并不是随便写个数字就会保存到常量池,只有大于2个字节的整形才会保存到常量池
movaxbxcxdx 2012-07-20
  • 打赏
  • 举报
回复
在一篇文章中说:常量池指的是在编译期被确定,并被保存在已编译的。class文件中的一些数据。除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值(final)还包含一些以文本形式出现的符号引用。详见:http://sd.csdn.net/a/20120629/2806999.html
这句话不是说常量池包含了各种基本类型?是不是原文有错误和疏漏呀?
张自强 2012-07-20
  • 打赏
  • 举报
回复

int 是基本类型,直接存数值
Integer是类,产生对象时用一个引用指向这个对象
Java把内存划分成两种:一种是栈内存,另一种是堆内存
在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配
而实际的对象是在存储堆内存中

int i = 9;//直接在栈中分配空间
Integer i = new Integr(9);//对象是在堆内存中,而i(引用变量)是在栈内存中
在堆中分配的内存,由java虚拟机的自动垃圾回收器来管理.
龙四 2012-07-20
  • 打赏
  • 举报
回复
在java栈的局部变量区
Integer a=9;等价于Integer a = Integer.valueOf(9);在堆中

java栈更多信息:http://www.ticmy.com/?p=151

50,504

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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