【发布时间】:2011-07-09 09:08:49
【问题描述】:
如果我写
String s= new String("how many object b created by this method ");
与这样做相比,将创建多少参考对象和对象:
Sting s1="Is this method is good as compare to upper";
【问题讨论】:
标签: java
如果我写
String s= new String("how many object b created by this method ");
与这样做相比,将创建多少参考对象和对象:
Sting s1="Is this method is good as compare to upper";
【问题讨论】:
标签: java
使用String s= new String("how many object b created by this method "); 创建一个String类的新对象's',你将字符串“这个方法创建了多少个对象b”传递给它的构造函数。
在String s1="Is this method is good as compare to upper"; 's1' 是一个字符串文字。关于字符串文字:
每次您的代码 创建一个字符串文字,JVM 首先检查字符串文字池。 如果字符串已经存在于 池,对池的引用 实例返回。如果字符串确实 池中不存在,一个新的字符串 对象实例化,然后放置在 游泳池。 Java可以做到这一点 优化,因为字符串是 不可变的,可以在没有的情况下共享 担心数据损坏。
以上概念与string interning有关;所有文字字符串和字符串值常量表达式都在 Java [source] 中实习。所以基本上,只有当"Is this method is good as compare to upper" 不在池中时,使用String s1="Is this method is good as compare to upper"; 才会创建一个新对象。
【讨论】:
使用String s1="some string" 不会创建新的字符串对象。每个 String 字面量都已经存在 String 对象。
具有相同值的字符串字面量用单个字符串对象表示,因此如果您同时使用String s1="some string"; String s2="some string";,则s1、s2 指的是相同的"some string" 对象。
new String("...") 创建一个新的 String 对象,它使用与 String 对象相同的数据来传递给构造函数的值“...”。
【讨论】:
考虑:
String s1 = new String("hi");
String s2 = new String("hi");
System.out.println(s1 == s2);
将打印false。
然而
String s1 = "hi";
String s2 = "h1";
System.out.println(s1 == s2);
将打印true。
还有
String s1 = "hi";
String s2 = new String("hi");
System.out.println(s1 == s2);
将打印false。
这就是为什么在比较Strings 时应该始终使用String.equals 而不是==。
但不要相信我的话...查看Java语言规范JLS 3.10的这段摘录:
Thus, the test program consisting of the compilation unit (§7.3):
package testPackage;
class Test {
public static void main(String[] args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }
and the compilation unit:
package other;
public class Other { static String hello = "Hello"; }
produces the output:
true true true true false true
This example illustrates six points:
Literal strings within the same class (§8) in the same package (§7) represent references to the same String object (§4.3.1).
Literal strings within different classes in the same package represent references to the same String object.
Literal strings within different classes in different packages likewise represent references to the same String object.
Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.
Strings computed by concatenation at run time are newly created and therefore distinct.
The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents.
【讨论】:
other.Other 令人困惑,直到我意识到小写的 other 是一层深的包名称,而不是缺少的变量或字段。
在Java中创建String对象有两种方式:
使用 new 运算符。例如,
String str = new String("Hello");
使用字符串文字或常量表达式)。例如,
字符串 str="你好"; (字符串文字)或
字符串 str="Hel" + "lo"; (字符串常量表达式)。
字符串文字池:
字符串分配,和所有对象一样 分配,在这两个时间都被证明是昂贵的 和记忆。 JVM 执行一些 实例化字符串时的诡计 文字以提高性能和 减少内存开销。削减 创建的 String 对象的数量 在 JVM 中,String 类保持一个 字符串池。每次你的代码 创建一个字符串文字,JVM 首先检查字符串文字池。 如果字符串已经存在于 池,对池的引用 实例返回。如果字符串确实 池中不存在,一个新的字符串 对象实例化,然后放置在 游泳池。
【讨论】:
使用 NEW 关键字创建 String 对象总是会在堆中创建一个包含所需字符串的对象,并返回堆中创建的对象的引用。
创建没有 NEW 关键字的 String 对象(使用文字)首先检查字符串文字池中具有相同数据的现有字符串,如果找到,则返回来自字符串文字池的相同引用,否则,一个新的在字符串字面量池中创建并返回其引用。
【讨论】: