在java中 为什么申明的字符串 1、String a="abcd";
在if(a=="abcd")
这个成立。
2、但是如果是用 String a= new String("abcd");
在if(a=="abcd")
就不成立了。
我看到书上解释的是,== 是检查两个数是不是指向同一个对象,
equals();是检查的构成两个操作数的内容是否相同。
现在我想明白的是,1、直接赋值 和 2、new 后赋值 它们对象会改变,那是怎么改变的呢?那到底具体什么时候应该用2、new 赋值好,什么时候直接用1、赋值好呢?
在if(a=="abcd")
这个成立。
2、但是如果是用 String a= new String("abcd");
在if(a=="abcd")
就不成立了。
我看到书上解释的是,== 是检查两个数是不是指向同一个对象,
equals();是检查的构成两个操作数的内容是否相同。
现在我想明白的是,1、直接赋值 和 2、new 后赋值 它们对象会改变,那是怎么改变的呢?那到底具体什么时候应该用2、new 赋值好,什么时候直接用1、赋值好呢?
解决方案 »
- 没多少分!但是还是希望众人拾柴火焰高吧!想统计下大家知道的例外、异常,能帮助新手尽快的处理问题!我先发几个
- 关于struts2.0的validator问题
- 路过的朋友请帮忙看看这个程序
- java 如何读取pdf文档?
- 怎样把文本文件中的中文词组(每个词组之间有空格做为分割符)写入mysql数据库的表中
- 一个简单而有趣的类型转换问题
- 我刚建立的一个QQ群,希望可以给提供学习Java的朋友一个互相交流的空间!(群号:3611831)
- 请问我该如何做!
- jbuilder5光标错位
- java创建用户界面,读取txt文件,进行用户和密码验证
- 请问final的方法一定不能override吗?
- 如何把一个类向下转型为它的内部类?
楼主【sai_show】截止到2008-07-15 00:32:54的历史汇总数据(不包括此帖):
发帖的总数量:3 发帖的总分数:90 每贴平均分数:30
回帖的总数量:3 得分贴总数量:0 回帖的得分率:0%
结贴的总数量:3 结贴的总分数:90
无满意结贴数:0 无满意结贴分:0
未结的帖子数:0 未结的总分数:0
结贴的百分比:100.00% 结分的百分比:100.00%
无满意结贴率:0.00 % 无满意结分率:0.00 %
敬礼!
最好不要用new String 这种语法。
也不能说String a="abcd"没有创建对象,"abcd"是对象池中的,如果对象池中没有才创建。
String b="abcd";
a和b其实是指向同一个对象,所以==为true。
而用new方法得到的是在堆上的不同对象。所以==判断为false;但是equals方法得到结果为true。
可以写个简单的例子测试一下。
想请ZangXT 还能比较具体点讲解下 这个 “堆” 具体点的概念,或者说 “堆”是个什么样的概念,我个人觉得是否它也是针对于 内存空间来定义的内容!!
public static void main(String[] args) {
String a=new String("abc");
String b="abc";
String c="abc";
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}它对应的虚拟机指令是:Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: returnpublic static void main(java.lang.String[]);
Code:
0: new #2; //class java/lang/String
3: dup
4: ldc #3; //String abc
6: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1
10: ldc #3; //String abc
12: astore_2
13: ldc #3; //String abc
15: astore_3
16: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_1
20: invokevirtual #6; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
26: aload_2
27: invokevirtual #6; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
30: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
33: aload_3
34: invokevirtual #6; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
37: return}从中可以看到,三个对象都是通过ldc #3得到的。对于new的String对象,先执行 0: new #2; //class java/lang/String
3: dup
两条指令,而其他两个直接赋值的对象都是直接加载常量区的字符串“abc”了
Object o=new Object();
是在堆中创建一个实际的Object()对象,变量o是对该对象的引用,但o存在于栈上,当出了当前作用域之后o就不存在了,但堆中的该对象还存在。
通过你9楼的介绍,我是否可以这样理解:
Object o=new Object();
这个是一个声明并实例化对象的表达,其实这个里面 真正所谓的对象是 Object(); 而o 只是个代替Object();进行具体操作的变量,
而且 Object();和 o 是在不同的内存空间中?
我这样理解对吗?
那这样说来 在堆里面创建的Object对象是个抽象的,它在内存分配了空间, 那当他的变量o进行具体操作的时候 操作的数据交换到底是在 Object这个对象所在的堆这个空间进行的呢? 还是在o这个对象变量的栈空间里面进行的呢?
比如
StringBuffer buffer=new StringBuffer("hello ");
buffer.append("world");开始在堆上创建一个StringBuilder对象,它的内容是hello ;buffer存在于栈中,它保存了对该对象的引用。
buffer.append("world")之后,堆中他引用的对象的数据就变成了hello world;
如果你再让buffer=new StringBuilder("test");
这是buffer就指向了堆中的另一个对象,它的数据是test。但原来数据为"hello world"的对象让然存在于堆中,只不过现在没法引用到它了,java虚拟机会在适当的时候自动回收它的内存空间。