1.直接赋值:String s = "1234567890"; 2.new对象: String s = new String("1234567890");如果你需要大量的使用s,那么请使用第一种方式。因为第一种方式中"1234567890" 该字符串在方法区的常量池里面,每次取s都是取得这个常量,你可以通过String s1 = "1234567890";String s2 = "1234567890";s1==s2来看看结果,结果是true。而第二种方式,他产生的"1234567890"字符串 是在堆中生成,并且每new一次,都会分配一块新的内存来保存该字符串。虽然占用的内存不多,但是大量的话就不太好。所以从效率方面看,大量使用同一个字符串的话肯定是第一种方法好,因为他用的是同一个常量池里面的字符串。
那你还是支持我的结论?还是认为终归是new的方式会多出一步去创建堆中的对象?
我在附加一句吧,拿3楼的例子来说,大量的new,会产生大量的无用的对象,众所周知,java是自己清理垃圾的,当年轻代的空间不足,或者年老带不足,会引发GC活着FGC,而GC和FGC都是需要时间的,尤其是FGC会耗费大量的时间。所以不能疯狂的new。如果经常使用一个字符串,那就定义成常量,每次都是使用同一份。就如这样String s = "1234567890";或者定义一个static final String。
以上个人觉得
楼主说看到时间会比较短,我这里实在看不出来,我循环了100000000,楼主可以看下执行结果的区别import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;/**
* @ClassName: Test1
* @Description: TODO(这里用一句话描述这个类的作用)
* @author chenjw
* @date 2012-7-16 下午5:38:28
*/public class Test1 {
public static void main(String args[]) throws IOException{
long start = System.currentTimeMillis();
String str;
for(int i=0;i<100000000;i++){
str = new String("abc");
}
long end = System.currentTimeMillis();
System.out.println("new String,it takes " + (end - start));
start = System.currentTimeMillis();
String str1 ;
for(int i=0;i<100000000;i++){
str1 = "abc";
}
end = System.currentTimeMillis();
System.out.println("it takes " + (end - start));
start = System.currentTimeMillis();
String str2 ;
for(int i=0;i<100000000;i++){
str2 = "abc";
}
end = System.currentTimeMillis();
System.out.println("it takes " + (end - start));
}
}运行结果:
new String,it takes 1201
it takes 35
it takes 35
执行步骤:
1. String 内存块中查找 对象,不存在则创建
2. s1 指向 内存块中的地址String s1 = new String("12345678901")
执行步骤:
1. String 内存块中查找 对象,不存在则创建
2. 拷贝对象值,堆中开辟一块空间并赋予值
3. s1 指向堆中地址
其实创建了俩对象。
赋值会在池中创建新的字符串;频繁赋值建议用StringBuffer
1.电脑的配置性能
2.添加了System.out.println();方法会影响结果。
------------------------------------------------
public static void main(String[] args) {
// TODO Auto-generated method stub
long time1=System.currentTimeMillis();
for(int i=1;i<1000000;i++){
String a=new String("123456");
}
long time2=System.currentTimeMillis();
System.out.println(time2-time1);
for(int i=1;i<1000000;i++){
String a= "123456";
}
System.out.println(System.currentTimeMillis()-time2);
}
---------------------------------------
运行结果:
39
1
2.new对象: String s = new String("1234567890");如果你需要大量的使用s,那么请使用第一种方式。因为第一种方式中"1234567890" 该字符串在方法区的常量池里面,每次取s都是取得这个常量,你可以通过String s1 = "1234567890";String s2 = "1234567890";s1==s2来看看结果,结果是true。而第二种方式,他产生的"1234567890"字符串 是在堆中生成,并且每new一次,都会分配一块新的内存来保存该字符串。虽然占用的内存不多,但是大量的话就不太好。所以从效率方面看,大量使用同一个字符串的话肯定是第一种方法好,因为他用的是同一个常量池里面的字符串。
http://www.amazon.cn/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Java%E8%99%9A%E6%8B%9F%E6%9C%BA-JVM%E9%AB%98%E7%BA%A7%E7%89%B9%E6%80%A7%E4%B8%8E%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5-%E5%91%A8%E5%BF%97%E6%98%8E/dp/B0058FLC22/ref=sr_1_1?ie=UTF8&qid=1345562786&sr=8-1
我不是推销的,但是觉得这本书真的非常不错,讲的也通俗易懂,如果楼主想搞java的话时必备的,我这几天在第二遍翻这本书。确实不错的
我全是上面推荐的那本书上看的。很多虚拟机例如HOT SPOT把整个堆空间分成年轻代和年老带,看名字就很好理解,年轻代就是存一些新创建的对象,而年老带就是放一些实用了很久了但是还在用的对象。当年轻代的快满时会进行GC 也叫YoungGC,这个处理会把年轻代里面一些没有用的对象给清理掉。然后年轻代里的一部分对象满足一定条件的时候会移动到年老代,这样年老代也会不断增大,当增大到一定程度就会触发FGC,这个耗费时间相比YGC会大好几十倍。因为会同时清理年轻代和年老代,把没用的对象给清理掉。
方式一:String s1="123"; 只开辟了一块内存保存“123”,变量s1指向那块物理地址。
方式二:
String s2=new String("123");步骤。
1.跟上面的一步是一样的。
2.new 对象时有开辟了一块内存,同时把“123”也复制过来。最终变量s2指向是第二块内存的物理地址。