我只知道一个是“b”,一个是引用它的a
为什么有人说这是3个对象呢?
为什么有人说这是3个对象呢?
解决方案 »
- 我想知道java中的简单类型的取值范围,要求在java.sun.com官网的答案,感谢
- 一个struts的简单问题
- 把cs的界面导出成xml文件2
- 如何取得JTEXTAREA的值??
- 帮我看看呀前辈们,有7个错误...............................................
- 在CORBA中,如何处理多个请求
- 汉字组成的字符串转成char[]数组,再组合起来就出现乱码
- 我在执行javac命令的时候没有问题,但是在执行java命令的时候却报如下错误
- 谁有redhat7.2下安装Jbuilder5的经验?!
- java 数据采集
- java如何操作word,急!!!
- 请问如何循环读出xml中子节点的名称及内容(内祥)
为什么是2个呢?
new一个b放在对象池里。a只是对b的引用
System.out.println("b" == new String("b"));
String sg = new String("bb");
String a 这个变量是指向当前对象的一个引用吧。
String sg = new String("bb");这样是一个
mystic
等 级:
发表于:2007-12-14 17:15:1916楼 得分:0
String s="b";这样才是两个
String sg=new String("bb");这样是一个
--------------------------------------
无语...
不信你看源代码
public String(String original) { //构造函数
int size = original.count;
char[] originalValue = original.value; //第一个字符串生成...
char[] v; //声明第二个字符串
if (originalValue.length > size) {
// The array representing the String is bigger than the new
// String itself. Perhaps this constructor is being called
// in order to trim the baggage, so make a copy of the array.
v = new char[size];//第二个字符串生成
System.arraycopy(originalValue, original.offset, v, 0, size);
} else {
// The array representing the String is the same
// size as the String, so no point in making a copy.
v = originalValue; //第二个字符串生成 }
this.offset = 0;
this.count = size;
this.value = v; //第三个字符串 .注意这里的value是String类里面的变量。
}
如果不相信你可以去看看相关java考试证书的书籍,上面写的很清晰。
一个字符对象,string a
一个字符对象的引用对象,new string("b");
看:
String s= "Hello ";
s= "Java ";
String s1= "Hello ";
String s2=new String( "Hello "); 啊,s所引用的string对象不是被修改了吗?之前所说的不变性,去那里了啊? 你别着急,让我告诉你说发生了什么事情:
在jvm的工作过程中,会创建一片的内存空间专门存入string对象。我们把这片内存空间叫做string池。 String s= "Hello ";当jvm看到 "Hello ",在string池创建string对象存储它,并将他的引用返回给s。
s= "Java ",当jvm看到 "Java ",在string池创建新的string对象存储它,再把新建的string对象的引用返回给s。而原先的 "Hello "仍然在string池内。没有消失,他是不能被修改的。 所以我们仅仅是改变了s的引用,而没有改变他所引用的对象,因为string对象的值是不能被修改的。 String s1= "Hello ";jvm首先在string池内里面看找不找到字符串 "Hello ",找到,返回他的引用给s1,否则,创建新的string对象,放到string池里。这里由于s= "Hello "了,对象已经被引用,所以依据规则s和s1都是引用同一个对象。所以 s==s1将返回true。(==,对于非基本类型,是比较两引用是否引用内存中的同一个对象) String s2=String( "Hello ");jvm首先在string池内里面看找不找到字符串 "Hello ",找到,不做任何事情,否则,创建新的string对象,放到string池里面。由于遇到了new,还会在内存上(不是string池里面)创建string对象存储 "Hello ",并将内存上的(不是string池内的)string对象返回给s2。所以s==s2将返回false,不是引用同一个对象。 好现在我们看题目:
String s = new String( "xyz ");
首先在string池内找,找到?不创建string对象,否则创建, 这样就一个string对象
遇到new运算符号了,在内存上创建string对象,并将其返回给s,又一个对象 所以总共是2个对象
mystic
等 级:
发表于:2007-12-14 17:15:1916楼 得分:0
String s="b";这样才是两个
String sg=new String("bb");这样是一个
--------------------------------------
无语...
------------------------------------------
人才!!!
如果能看中间代码的情况就能看到分配几个空间了。
我认为应该是1个~~
“*”要先检察池内是否存在对象
NEW 不管怎样都会创建新的对象
所以两个
String a 的意思是定义一个引用,= new String("b")的意思是动态产生一个String对象并返回给引用a.
许多人都没有搞清楚!
要想想如果做一个JVM,怎么才正确?
String a = "b";//一个String对象,常量池中;一个String类型引用,栈中
在java里面存在堆里面的东西才称为对象,基本数据类型(如:int,char)都存放在栈里面的。
String s="xyz";
引用s 和“xyz”都是存放在栈中的东西,不是对象
new String("xyz");这个才是产生对象的
所以就1个对象
a 是一个reference, 相当于c++中的指针, new String("b"); 是创建一个String, 用"b"来初始化, "b"在java中也可以认为是一个String对象,可以执行诸如"b".length()的操作.有几个对角没考虑过
因为这是一个java面试时常用的问题,
"
太搞笑了, 共享池里创建了一个对象, 不直接引用, 还跑去再创建一个, 浪费内存啊,你们以为jvm的作者是傻蛋啊。
"对于C++语言来说..显然就一个...我一看题目就觉得是1个对象,1个引用..我对JAVA理解不多,所以不好说什么...但如果答案真的是2个..
我会比较鄙视jvm的作者的..
设计的时候: 一个"bb"和new string("bb") 按着一般的道理应该是同一位置的..
因为string又不能改变,你TMD的在内存里弄那么bb,, 这bb1 ,那bb2的觉得用户的内存很多吗???但如果string是能改变的话.."bb"和new string("bb")是需要不一样的..因为我们会改变后者,这时就不能在常量区操作了,的确需要给bb弄块内存出来...所以要是我来设计jvm(只是设计 ^_^), string a=new String("b"), 我就会把"bb" 和a引用 放一个位置上,都是常量区..
当然判断方法24楼也已经说了..你创建个一个string("aa"),看它和常量区的"aa"比下是不是一个位置,c++当然好说.我不知道java能不能比..本人最后观点: 应该是一个..如果是两个..痛骂JVM的作者.妈的真是个傻蛋.哈哈 我又找到一条java垃圾的证据了.老妈一直催着吃饭...所以很可能理解出现大错误... 如果那样的话.嘻嘻 本人也是菜鸟...
另外骂 "JVM作者什么傻蛋" 只是玩笑.突然想到new怎样处理应该是编译器作者的事情...哦..看来不关jvm作者的事情..不管怎样 我已经晕了 ..吃饭去也..
等 级:
发表于:2007-12-17 10:56:0954楼 得分:0
搞清楚这个问题,先要弄懂java里面堆和栈的概念
在java里面存在堆里面的东西才称为对象,基本数据类型(如:int,char)都存放在栈里面的。
String s="xyz";
引用s 和“xyz”都是存放在栈中的东西,不是对象
new String("xyz");这个才是产生对象的
所以就1个对象
=============“xyz”不在栈中,而是在String的常量池内,是内存中一块特殊的区域,所以“xyz”也是对象,共2个
new String("b");这样也是两个啊.
"b"创建一个,new出来一个.
"b"明显是一个
new出来的也是一个
""b"明显是一个
new出来的也是一个"对于new,确实 平常的意思就要new出来一个..但是在这里由于string不能被改变..大家注定是一样的..
就不应该再new一个...否则就是浪费内存了... 所以代码要求new的时候.."编译器"并不真正的new,而是检查发现已经有
"bb"了 就直接指向常量区...反正用户也不能改变string,就不会出错的.所以说问题就看java "编译器"怎么对待new这个操作符了... 如果"new"真的一直一味不变当作new处理,我会鄙视JAVA的.
呵呵...C++里的new是十分聪明的...24楼的回答,我也看了..我看见2个的答案的时候 就知道解释肯定会这样说的...我心里只是觉得多分配个内存出来很不爽..
所以觉得应该只有一个... 我60 楼的..
怎么能是两个啊
在新建String类型时,编译器会首先看看在对象池里有没有和要new的对象一样的名字,如果有编译器就不会
再新建一 个了。直接指向那个对象。如果没有就会新建一个。所以就是一个对象啊!
Java里new关键字一定是会分配内存空间,产生新的对象,这不能说Java没有C++“聪明”,不同编程语言在设计理念上会有不同,Java语言的语法还是以简洁为主要设计目标(虽然现在越来越复杂),new关键字会在不同的情况下保证有相同的语义;而且因为Java语言提供的垃圾回收机制,就像C#的托管机制一样,一般来说内存的使用效率不是首要考虑的因素,可能你习惯了C++,所以才会觉得多分配个内存出来很不爽..
a是一个引用,指向一个在heap区中被新创建的对象
b是一个String类型常量,应该在常量池里面,在类的字节码被加载的时候创建的
所以,我猜应该是2个对象
支持2个对象String a = new String("b");
可以拆分成如下2步操作
String b = "b"; // 创建一个字符串对象 b
String a = new String(b); // 此时,会再次创建一个对象a;帖一段测试代码和运行结果
public class TestString {
public static void main(String[] args) { String a = "b";
String b = new String(a);
String c = "b";
System.out.println("a==b?"+(a==b));
System.out.println("a==c?"+(a==c));
}
}
// 运行结果如下
a==b?false
a==c?true
it's two
如:1. String a="b"; // 产生一个
String a=new String("b");//这时,他就产生一个。因为String池中的已经有了,他就不用产生了。 2. String a=new String("b"); //这是他就产生了两个,因为String中还没有,所以他就必须先在池中产生一
个,然后再NEW一个出来。
String a="b"; //这时他就没有产生对象了。
其中后者更接近于C++中的String.
从某种意义上说,String其实是字符串常量而StringBuffer才是真正的字符串变量,这么理解的话JVM对这两者的处理机制就合情合理了.
它就字符串的处理给出了两种方式供使用者选择.另外,我个人认为C++和JAVA不存在谁垃圾的说法,它们面向不同的场合.
实际情况中,也许C++合适,也许JAVA合适.
硬要说JAVA垃圾是没有任何道理的.
以前还看见有人说C++垃圾,不如汇编纯粹,又不如SmallTalk抽象,我认为同样是无稽之谈.
程序员应该更关注某种语言的优点而非缺点.
上面的语句如果a本身不算对象的话
就可以肯定有2个对象
看下面的描述从上面的语句看最后结果 string类型的a 引用了一个 string (这里是一个)
这个被引用的string 来自 new string(xxx) (他是被a引用的所以这里不是新的)
new string(XXX)中的初始化值XXX 你能说他不是对象吗?(所以这里又是一个)
这样不是2个 是几个?可以说string a="b"; 和 string a=new string("b"); 明显的一样效果
94楼:“new string(XXX)中的初始化值XXX 你能说他不是对象吗?(所以这里又是一个) ”
XXX只是一个字面字面上的值而已,按你的说法我给小孩取名XXX,那么XXX也是个人了,就有两个小孩了同意86楼,栈中一个引用,堆中一个对象
当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。
它遵循对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
所有字面值字符串和字符串赋值常量表达式都是内部的。字符串字面值在《Java Language Specification》的 §3.10.5 中已定义。
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. 返回:
一个字符串,内容与此字符串相同,但它保证来自字符串池中。
String strA = "hello";
String strB = new String("hello");
strA == strB显然会返回false
那么
int i = 1;
int ii = 1;System.out.println(ii == i);//返回true
可现在一个对象也没有另外
String s = null;
String ss = null;
System.out.println(ss == s);//返回true
现在有几个对象?再另外
String s = "a";
String ss = "a";
System.out.println(ss == s);//返回true
现在又有几个对象?