原帖:
http://community.csdn.net/Expert/topic/3898/3898233.xml?temp=.7976496==============================================================================
哈哈。我认为是对的。相信有很多人不清楚。
一个是new 出来的。被s引用着;
还有一个是"xyz",这个也是一个对象!实际上java先为字符串常量创建了无名字符串对象。然后在通过new String创建一个新的String对象
http://community.csdn.net/Expert/topic/3898/3898233.xml?temp=.7976496==============================================================================
哈哈。我认为是对的。相信有很多人不清楚。
一个是new 出来的。被s引用着;
还有一个是"xyz",这个也是一个对象!实际上java先为字符串常量创建了无名字符串对象。然后在通过new String创建一个新的String对象
String不停的创建对象,StingBuffer不停地改变自己!
创建的是一个对象,而"xyz”也是一个对象没错,但是它的创建和这条语句是没有关系的。它是程序String Pool中的一个对象,可能在使用这条语句前很久就已经创建出来了。
==================
一个是new 出来的。被s引用着;
还有一个是"xyz",这个也是一个对象!"xyz"就是一个无名对象啊!也是由java创建的!to: gary_choi()
创建了几个对象是由java做的。 不如何!我不赶把它怎样!!to: 007remember(绿原)
你的那段文字我不止看到3次了。你去看看java里有关字符串的描述:
“...在java中,用双引号括起来的字符串是字符串常量;又称无名字符串对象,由java自动创建”to: jihanzhong(逍遥)
object XXX=new object();是只创建一个对象的!
你说的很对。我也这么认为。它只创建了一个对象。可现在的情况是:
String s=new String("xyz");//不知道你有没有看到"xyz"这个东东;它也是一个对象啊!to: nimifeng
这是您的自由,保持!
这是String构造函数中的一个参数啊。怎么说没关系呢?不理解。 请指点;还有就是 假如 Pool里没有"xyz"这个对象呢?他照样也会在执行 语句String s=new String("xyz");时一起创建
如是这样说的话。那它只能说有可能创建2个对象吗?(就是要看pool里有没有)
Strind s=new String();//可以这样么?---------------------------String s1="cddf";
String s2=s1;
//一共几个对象?-------------------------------------
object XX=new object("初始值");//几个对象?------------------------------------------object X1=new object("初始值");
object X2=X1;
//一共又是几个对象?
创建了一个对象!! 一个是句柄,一个是对象!!
是的,双手赞同!
Strind s=new String();//可以这样么? 可以---------------------------String s1="cddf"; 可能1(要看池里有没有"cddf")
String s2=s1; 0
//一共几个对象? 共计:可能1-------------------------------------
object XX=new object("初始值");//几个对象? 可能2个,至少1个。------------------------------------------object X1=new object("初始值"); 可能2个,至少1个。
object X2=X1; 0
//一共又是几个对象? 可能2个,至少1个。
=========================================================================
String s1="cddf"; 这个创建了几个对象就是了。如果String pool里已经有了"cddf",那这条语句仅仅创建了一个String类的reference
但是如果没有的话。java编译器首先是创建一个字符串常量(要知道这也是一个类,一个匿名类)"cddf"
建好了后再把这个匿名类的地址给s1。 你能理解我说的意思么?
建好了后再把这个匿名类的实例"cddf"的地址给s1。 你能理解我说的意思么?
^^^^^^^^^^^^
String s1 = new String("abc");
//创建二个对象, 一个是"abc", 一个是包裹"abc"的String对象String s2 = new String("abc");
//创建一个对象, 因为"abc"已经被创建了, 不再重新创建
而下面的代码:String s1 = "abc";
//创建一个对象"abc"String s2 = "abc";
//没有创建新的对象, 只是将s2也指向"abc".
相互学习。我也是几天前看到相关资料后阐述的自认为正确的观点。把它放到网上来。
和大家一起切磋。每次讨论,都会有新的收获。我也更加相信自己的观点。0_-!!共同进步!
re: Dan1980 那:
String s1 = "def";
String s2 = "def"
创建了几个对象呢?(现在假设String pool里原先没有"def");
自己动手,丰衣足食
String s1 = "def";
String s2 = "def"
创建了几个对象呢?(现在假设String pool里原先没有"def");
-------------------------------------------------------------
创建了一个对象, 即"def".
您所说
=============================================================
String s1 = new String("abc");
//创建二个对象, 一个是"abc", 一个是包裹"abc"的String对象
=============================================================
创建的"abc"本来就是一个String对象,为什么还要创建一个 包裹"abc"的String对象
不就是2个对象了么 ?
不就是2个对象了么 ?
//-----------------------
答: 如果Pool里已经有了"abc",则不创建新对象,引用a指向"abc"文字量
如果Pool里没有"abc",则在Pool中自动创建"abc"文字量,然后引用a指向它.总之,这一句或者没有创建新对象,或者创建1个,绝不会是2个! Dan1980(也该有一些作为了) 说的对!
去看看有关String s = new String("string");的说明吧。
不管Pool里有没有"string";都会生成一个新的对象的。这样写清楚些:
String stemp = "string"; //这里才是你所谓的可能创建了一个对象。
//要看String Pool里面有没有了。
String s = new String(stemp);//这里是100%回Create出一个Object的。知道吗?
//这是一个非常基础的问题。。
再告诉你一点:
Dan1980 说的和 你 说的是两回事。
不过你们两个结合一下就对了。
选自<Effective JAVA> 原著: Joshua Bloch 翻译:Dan
-----------------------------------------------------------------
第四条:避免创建重复的对象以重用单个对象来代替每次需要时都创建一个新的功能相当的对象通常是合适的。重用可以既快速又更时髦……作为一个不这样做的极端的例子,考虑下面的语句:String s = new String("Silly"); //DON'T DO THIS!这条语句每次被执行时都创建一个新的String实例,并且那些对象的创建中,没有一个是必需的。作为String的创造器的参数"Silly"本身是一个String实例, 功能与每次由创造器创建的对象完全一样。如果这种用法发生在一个循环结构或一个频繁调用的方法中, 数以百万的String实例会不必要地被创建。改进版本很简单地如下:String s = "No longer silly";这个版本使用一个单一的String实例,而不是每次执行都创建新的对象。而且,它保证了对象将被在同一个虚拟机上运行的正好在使用同一个字符串字面量的其它代码重用。
如id=152
String str4=new String("abc");//创建了str4的实例,并value的id指向 152结:这种情况下String str3=new String("abc");创建一个实例,并系统创建值为"abc"的匿名有id的实例,即创建两个实例.而String str4=new String("abc");因为str3已建了"abc"所以它只建了一个实例.
看看这个例子:String str1 = "hello!";
String str2 = new String(str1);
str1 = "hello, world!" //并非修改str1对象的值。看似修改str1的值,其实是创建一个新对象,然后修改str1之引用可以看出,想修改一个String对象内部的值可不太容易(trim()、toUpperCase()等都不会修改String对象本身的值),所以JAVA String对象本质上是不变的常量,除非有充分的理由需要显式创建一个String对象的副本,否则没有必要使用new String(xxx)。
唯一要注意的是当比较字符串的时候,比较引用是很危险的,要用equals
final int PI = 3.14;
final int PI_BAK = 3.14;上述代码没有必要。同理:所以也就没有必要使用new String("xxx")来创建一个String对象的副本。
-------------------
这个并不重要,因为java是运行时优化,肯定是生成的对象越少越好,String本身不能改变内容,所以做一个常量池是很有可能的
唯一要注意的是当比较字符串的时候,比较引用是很危险的,要用equals同意!!!
非常感谢您提出的宝贵资料。但我看了之后并还不确信我的观点是错误的。
我就要下班了。等我做测试后在给您汇报结果 0_-!!
to: wa0clever(不懂→问)
String str3=new String("abc");//创建了str3的实例并缓冲池中创建值为"abc"的匿名有id的实例,
如id=152
String str4=new String("abc");//创建了str4的实例,并value的id指向 152
告诉你。你错了。看看Dan1980翻译的资料吧。re llihua(Hill)
您在上面回复到: "String s = new String("Silly"); 调用了String(String original)这个构造函数,
当String 池中没有这个对象时,是创建了两个对象。"
--这是我的观点.呵呵。。看仔细了。 final int PI = 3.14;
final int PI_BAK = 3.14;
--这是基本数据类型。和Object(String)不同。不能先比较。
re llihua(Hill)
您在最后说的是 有没有必要么?
哦。是我理解错了。
不过我们现在讨论的是当在重复定义的情况下。它怎么做。并不是必要不不要的问题。
还有就是,假如在一个循环体里面呢?重复定义并非是我们的意愿。
但如果疏忽的话。。呵呵。~~~
谢谢你的指教,让我认真去考虑问题,我把String类的构造方法复制过来,大家看看,
我是有点迷惑了.2种情况下一种创建新数组,而另一种情况直接赋值了. public String(String original) {
this.count = original.count;
if (original.value.length > this.count) {
// 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.
this.value = new char[this.count]; //????????????????
System.arraycopy(original.value, original.offset,
this.value, 0, this.count);
} else {
// The array representing the String is the same
// size as the String, so no point in making a copy.
this.value = original.value; //?????????????
}
}
你写了这么多。不是给我的观点做立论么? 你先看我的观点;后在发表您的观点好么?
------------------
光:
String s1 = new String("abc");
String s2 = new String("abc");//创建了两个对象。
光:
s1 = "abc";
s2 = "abc";//创建了一个对象。
--------------------------------------我一直都这么认为的。
仅这句: String str = new String("asdf");
先创建"asdf";这是一个。//有疑义么?假设Pool里面没有。
后做参数初始化新对象,并把地址给str;//无论如何,它都会new出一个对象来。
那不就是有两个了?(假设Pool里没有,否则只有一个。)
to :onlyxu(未透露姓名男子)
这里不讨论有没有实际意义。只讨论它的做法。
对于农民来说。学java没有实际意义 0_-!!
this.value = new char[this.count]; //你把String 理解为 char[]就通了。
//或看看前面关于value的定义.
this.value = original.value; //这里我认为仅一个引用;
一个非常恐怖的结果:
===============================================
public final class Strng { private final char value[];
private final int count; public Strng() {
count = 4;
value = new char[] {
'a', 'b', 'c', 'd'
};
}
public Strng(Strng original) {
int size = original.count;//为何这里能访问count;
char[] originalValue = original.value;
char[] v;
if (originalValue.length > size) {
v = new char[size];
System.arraycopy(originalValue, 0, v, 0, size);
} else {
v = originalValue;
}
this.count = size;
this.value = v;
}
public String toString() {
return new String(value);
}
public void change() {
value[count-1] = 'O';
} public static void main(String[] args) {
Strng s1 = new Strng();
Strng str = new Strng(s1);
s1.change();
System.out.println(s1);
System.out.println(str);
}
}
===============system.print:========================
D:\MyJava\CSDN>javac Strng.javaD:\MyJava\CSDN>java Strng
abcO
abcO不过我又做了一个测试:发现很是矛盾
public class StringTest { public static void print(char[] chr) {
for(int i=0; i<chr.length; i++) {
System.out.print(chr[i]+"-");
}
System.out.println("");
}
public static void main(String[] args) { char v[];
char val[] = {
'1', '2', '3', '4', '5', '6', '7'
}; String s0 = "abcd";
String s1 = new String("abcd");
String s2 = new String("abcd");
String s3 = new String(s1);
String s4 = new String(s2); System.out.println(s0==s1);
System.out.println(s1==s2);
System.out.println(s1==s3);
System.out.println(s2==s4); v = val;
val[3] = 'A';
print(v);
print(val);
System.out.println(v==val);
}
}
===================================傻了吧。两个结果反映两个观点!
D:\MyJava\CSDN>javac StringTest.javaD:\MyJava\CSDN>java StringTest
false
false
false
false
1-2-3-A-5-6-7-
1-2-3-A-5-6-7-
trueD:\MyJava\CSDN>
public static void main(String[] args){
String a="abc";
String b="abc";
System.out.println(a==b);}
}--------------
true
确实a和b都是一个对象
内容 String a = new ("abc");
是不是写错了?
======================================================
to: me5572 呵呵。。献丑了。
代表毛zx向大家道歉。
public class StringTest { public static void print(char[] chr) {
for(int i=0; i<chr.length; i++) {
System.out.print(chr[i]+"-");
}
System.out.println("");
}
public static void main(String[] args) { char v[];
char val[] = {
'1', '2', '3', '4', '5', '6', '7'
}; String s0 = "abcd";
String s1 = new String("abcd");
String s2 = new String("abcd");
String s3 = new String(s1);
String s4 = new String(s2); System.out.println(s0==s1);
System.out.println(s1==s2);
System.out.println(s1==s3);
System.out.println(s2==s4);
System.out.println(s0);
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
v = val;
val[3] = 'A';
print(v);
print(val);
System.out.println(v==val);
}
}结果:
false
false
false
false
abcd
abcd
abcd
abcd
1-2-3-A-5-6-7-
1-2-3-A-5-6-7-
true
======================
四个s是一样的耶
是一样的呀。!!"==" 做的地址的比较。并不是值的比较。你把String 理解为一个Object就是了。
它里面有一个toString()的方法。
我想问问 Dan1980(也该有一些作为了)
您所说
=============================================================
String s1 = new String("abc");
//创建二个对象, 一个是"abc", 一个是包裹"abc"的String对象
=============================================================
创建的"abc"本来就是一个String对象,为什么还要创建一个 包裹"abc"的String对象我已经明白String s1 = new String("abc");肯定会创建一个对象
我现在的理解是创建一个对象"abc",然后创建一个reference s1指向这个对象,所以我认为总共只创建了一个对象,至于您所说的 包裹"abc"的String对象 我有点不明白什么意思
一个是"abc", 一个是包裹"abc"的String对象
=====================================
这句话绝对的错了。这两个object根本没什么关系;更何况是 Nest.你记住,一个new 标志着一个obj的产生。即使是: new String();