站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2SE 专题一个简单的基础问题?

一个简单的基础问题?

摘要: 一个简单的基础问题?


小弟学了一个月的java 对一些基本的东西想弄清下
String str=new String(-#34;Hello World-#34;);

String str=-#34;Hello World-#34;;
有什么区别啊?


Java运行环境有一个字符串池,由String类维护。执行语句String str=-#34;abc-#34;时,首先查看字符串池中是否存在字符串-#34;abc-#34;,如果存在则直接将-#34;abc-#34;赋给str,如果不存在则先在字符串池中新建一个字符串-#34;abc-#34;,然后再将其赋给str。执行语句String str=new String(-#34;abc-#34;)时,不管字符串池中是否存在字符串-#34;abc-#34;,直接新建一个字符串-#34;abc-#34;(注意:新建的字符串-#34;abc-#34;不是在字符串池中),然后将其付给str。前一语句的效率高,后一语句的效率低,因为新建字符串占用内存空间。String str = new String()创建了一个空字符串,与String str=new String(-#34;-#34;)相同。


第一个创建了2个对象,第二个创建了1个对象。所以第一个消耗的资源大,不推荐


楼上的能说说清楚吗?我听过你的说法,而且很多人都这么说,但又感觉不对啊,为什么是两个啊,new String(-#34;Hello World-#34;)是一个,还有一个在哪里啊,
jackson416:你的字符串池问题能说下吗?那句新建的字符串-#34;abc-#34;不是在字符串池中,那到哪里去乐


常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。

看例1:

String s0=”kvill”;

String s1=”kvill”;

String s2=”kv” + “ill”;

System.out.println( s0==s1 );

System.out.println( s0==s2 );
结果为:

true

true

首先,我们要知结果为道Java会确保一个字符串常量只有一个拷贝。

因为例子中的s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中”kvill”的一个引用。

所以我们得出s0==s1==s2;

用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。

看例2:

String s0=”kvill”;

String s1=new String(”kvill”);

String s2=”kv” + new String(“ill”);

System.out.println( s0==s1 );

System.out.println( s0==s2 );

System.out.println( s1==s2 ); 结果为:

false

false

false
例2中s0还是常量池中”kvill”的应用,s1因为无法在编译期确定,所以是运行时创建的新对象”kvill”的引用,s2因为有后半部分new String(“ill”)所以也无法在编译期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。





String str=new String(-#34;Hello World-#34;); 中,
-#34;Hello World-#34;是一个 String 对象,
new String(-#34;Hello World-#34;)又创建了一个新的 String 对象


JVM为运行一个程序定义了几种数据区(Data Area),包括:pc寄存器、JVM堆栈、堆、方法区(Method Area)、运行时常量池(Runtime Constant Pool)以及本机方法堆栈(Native Method Stacks),这些数据区根据其生存期可以分为两种,一种就是和JVM的生存期相同(包括堆和方法区),一种和线程的生存期相同(其它的),和JVM生存期相同的数据区在JVM启动的时候被创建并在JVM退出的时候被销毁,而和线程生存期相同的数据区是每个线程一个的,他们在线程创建的时候被创建,在线程被销毁的时候被销毁。
String str=-#34;Hello World-#34;;---〉运行时常量池
String str=new String(-#34;Hello World-#34;);----#62;堆


没想到这个问题还挺复杂的哦 谢谢各位了


↑返回目录
前一篇: 一个问题,关于编程习惯
后一篇: 怎样在JSP中使用自己写的类