1和2等价
3只是声明,没有赋值
String在JAVA中比较特殊
3只是声明,没有赋值
String在JAVA中比较特殊
解决方案 »
- 关于java中异常处理的问题
- 使用JButton 的setEnabled(false)后,按钮变灰,但是单击后仍然会触发事件
- java日期处理
- 谁有JAVA版的CMPP3.0 API
- 我看到一个类里面有这个东西,但是没有语法错误,请问这是什么意思?
- 正则不分大小写字母转换,小问题,得就结
- java 系统参数
- 谁有“计算器”的源码呀!最好是手写的非ide编写的!谢谢
- 寻求一种小巧易用的JAVA编程工具。
- webloigc 6.0的问题
- 继承了一个jcomponet类生成一个组件,将组件放在一个jpanel中,想要设置组件的tooltiptext
- 哪位仁兄分部分JAVA的活做做,不用任何报酬,就为练手!
s3只声明,没有初始化(也就是没有赋值)。
String s3=null;则初始化了,但是s3指向null。
String s2 = "Happy";
String s3;
之间的区别?
你说前两个一样么??好像是不对吧?S1是一个对象的句柄,在存堆中。S2是一个JAVA的基本类型,它其中存放的是一个字符串,是放在椎栈中。
不知我这样认为对不对??
String s2 = "Happy";
String s3;
其中s1,s2,s3都是句柄,指向字符串对象. 当然,s3没有初始化,它指向的是null
s1 equals s2 但 s1 != s2 .s1,s2指向两个对象..
如果再定义一个 String s4 = "Happy"
则 s2==s4 .当然肯定s2 equals s4 ,因为s2和s4都指向同一个对象 ..呵呵,慢慢理解吧:) ------------------------------------------------------
我们还年轻牛奶会有的奶牛也会有的
可天天在 csdn 混这些会有吗 ??
String s2 = "Happy";
JAVA语言对String作了一些特殊处理,JAVA中唯一的一个运算符重载就是String 的等号
也就是你写的是s2 = "happy",但编译器给你处理成s2 = new String("happy");
所在happy也是在堆中
String s2 = "Happy";
看着是等价没错,但是绝对不一样的.String s1 = new String("Happy");是一个愚蠢的反例.如果大家会用javap,可以做试验看看.
另外, String s2 = "happy" 是从class的常量池中加载的.
public class TestString {
public static void main(String[] args) {
long start = System.currentTimeMillis();
for ( int i=0; i<10000000; i++ ) {
String s1 = new String("Happy");
}
long end = System.currentTimeMillis();
System.out.println("Duration:"+(end-start));
start = System.currentTimeMillis();
for ( int i=0; i<10000000; i++ ) {
String s1 = "Happy";
}
end = System.currentTimeMillis();
System.out.println("Duration:"+(end-start));
}
}
运行结果如下:
[zxh@spider zxh]$ java TestString
Duration:761
Duration:25
机器平台:P4 2.0G, Redhat linux 9.0, JDK1.4.1_02
说等价的朋友跳出来解释吧.
0 new #2 <Class java.lang.String>
3 dup
4 ldc #3 <String "Hello">
6 invokespecial #4 <Method java.lang.String(java.lang.String)>
9 putstatic #5 <Field java.lang.String s>而String s = "Hello";反编译是这样的:
0 ldc #2 <String "Hello">
2 putstatic #3 <Field java.lang.String s>我想就不需要再解释是否等价的问题了吧,请仔细看看上面的反编译结果.
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
String s1 = new String("Happy"+i);
}
long end = System.currentTimeMillis();
System.out.println("Duration:" + (end - start)); start = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
String s1 = "Happy" + i;
}
end = System.currentTimeMillis();
System.out.println("Duration:" + (end - start));
}
老兄想说明什么?还是后面的快啊.看看反编译的结果:
String s1 = new String("Hello"+i);
==========================================
4 new #3 <Class java.lang.String>
7 dup
8 new #4 <Class java.lang.StringBuffer>
11 dup
12 invokespecial #5 <Method java.lang.StringBuffer()>
15 ldc #6 <String "Hello">
17 invokevirtual #7 <Method java.lang.StringBuffer append(java.lang.String)>
20 getstatic #2 <Field int i>
23 invokevirtual #8 <Method java.lang.StringBuffer append(int)>
26 invokevirtual #9 <Method java.lang.String toString()>
29 invokespecial #10 <Method java.lang.String(java.lang.String)>
32 putstatic #11 <Field java.lang.String s>String s1 = "Hello"+i;
=========================================
4 new #3 <Class java.lang.StringBuffer>
7 dup
8 invokespecial #4 <Method java.lang.StringBuffer()>
11 ldc #5 <String "Hello">
13 invokevirtual #6 <Method java.lang.StringBuffer append(java.lang.String)>
16 getstatic #2 <Field int i>
19 invokevirtual #7 <Method java.lang.StringBuffer append(int)>
22 invokevirtual #8 <Method java.lang.String toString()>
25 putstatic #9 <Field java.lang.String s>运行结果:(三次)
[zxh@spider zxh]$ java TestString
Duration:14086
Duration:10955
[zxh@spider zxh]$ java TestString
Duration:14787
Duration:11848
[zxh@spider zxh]$ java TestString
Duration:14699
Duration:11772
楼主问的是 s1 s2 s3的区别,不是问怎样做提高性能...
s1 = new String("ssss") 是开辟一个新内存区域,建立一个新对象
s2="ssss" 是生成一个String 类型的句柄 s2,而它的值是在常量池里寻找.
如果再定义一个s3="ssss" ,则这是的s3和s2都指向同一个String,指向同一个对象空间..
但s1始终是和s2,s3不一样的,它有自己的对象空间..
这就是 new 和直接 = 的区别...
所以现在就是
s1 equals s2 为true 但 s1==s2为false,而s2==s3为true,当然肯定s2.equale(s3)也为true了
至于效率,那不是现在在讨论的 :)
------------------------------------------------------
我们还年轻牛奶会有的奶牛也会有的
可天天在 csdn 混这些会有吗 ??
7 dup
29 invokespecial #10 <Method java.lang.String(java.lang.String)>使用String构造函数,还是要多执行三条指令.
for(int i = 0 ;i<100000 ;i++)
String s1 = "Hello"+i;像这样的情况,用StringBuffer类比String要快 一千倍(或几百倍,以前做的测试,现在忘了) !!! ------------------------------------------------------
我们还年轻牛奶会有的奶牛也会有的
可天天在 csdn 混这些会有吗 ??
多谢解释,其实我明白楼主的意思.对于初学者来说,这个确实没有区别,而且new String()的方式好像还更为合理一点.
我只是想真正告诉他们new String和=""之后有什么区别,想让他们从开始就养成一个好的习惯来使用String. 等到后面明白String的immutable也就有好处的.
不是
for(int i = 0 ;i<100000 ;i++)
String s1 = "Hello"+i;
而是:
String s1 = "Hello";
for(int i = 0 ;i<100000 ;i++) {s1 += i;}
和
StringBuffer sbuf = new StringBuffer("Hello");
for(int i = 0 ;i<100000 ;i++) {sbuf.append(i);}
String s1 = sbuf.toString();
之间的比较.你的记忆没有骗你,确实效率相差太远了. :)
呵呵,其实你功底很不错呀 :)
说真的,那些底层的东西,我一直也没有仔细看呢...
唉,每天光赶项目,还是在学校好,可以自由的研究... 只是在学校的时候光玩了 :) ------------------------------------------------------
我们还年轻牛奶会有的奶牛也会有的
可天天在 csdn 混这些会有吗 ??
我上大学四年唯一都坚持下来的就是喝茶打麻将了. :)
s2="ssss" 是生成一个String 类型的句柄 s2,而它的值是在常量池里寻找.
看来是不一样,
我记得String是个不变类,是说不管你系统中有多少个ssss,它其实是所有的都指向同一个?
包括你用new String("ssss");
看来还是new出来了一个,呵,我说错了
还说错了一个,重载的是"+",不是"="
sorry~
public class Test {
public static void main(String[] args) {
StringBuffer sb1 = new StringBuffer("a");
StringBuffer sb2 = new StringBuffer("a");
System.out.println("sb1.equals(sb2) : " + sb1.equals(sb2));//<1>、为什么是false String s1 = new String("a");
String s2 = new String("a");
String s3 = "ssss";
String s4 = "ssss";
System.out.println("s1.equals(s2) : " + s1.equals(s2));//<2>、为什么是true
System.out.println("s1 == s2 : " + (s1 == s2));//<3>、为什么是false
System.out.println("s3 == s4 : " + (s3 == s4));//<4>、true
}
}
其中<2>、<4>上面的各位已经说清楚了,
可是<3>呢?是不是说“==”比较是句柄(地址),所以,s1和s2是不一样的?
<1>呢?请高人给说一说String和StringBuffer的区别??这个问题我一直想知道!!谢谢!!
<1>, StringBuffer类没有覆盖equals方法,所以当你对StringBuffer调用equals的时候,实际上是调用起父类Object的equals方法,而Object的equals方法是本地方法,比较的引用是否相等.所以你会得到false.
这样就是true了: sb1.toString().equals(sb2.toString());String是一个不变类,就是说在其生命周期内不会被改变.(只有在构造的时候才能赋值)
而StringBuffer是一个可变类.这就是最大的区别.
关于不变(IMMUTABLE)和可变(MUTABLE)的比较大致是这样的.
(1) 不变类是线程安全的,强壮;
(2) 使用不变类可能对造成垃圾对象的增多;
但是正常情况下,不变对象的优点还是很显著的.
我们所看到的基本类型的封装类都是不可变类,如Strng, Integer, Long, Byte等.
还有BigDecimal,BigInteger等.对于这些对象是不需要线程同步保护的.因为它们的值不会被修改.