Java字符串:“字符串s=新字符串(“愚蠢”);”
我是一个C++学习java的家伙。我正在读有效的Java,有些东西把我弄糊涂了。它说永远不要写这样的代码:String s = new String("silly");
因为它会创建不必要的String
对象。但应该这样写:
String s = "No longer silly";
好的,到目前为止还不错。。。然而,鉴于这一类别:
public final class CaseInsensitiveString {
private String s;
public CaseInsensitiveString(String s) {
if (s == null) {
throw new NullPointerException();
}
this.s = s;
}
:
:
}
CaseInsensitiveString cis = new CaseInsensitiveString("Polish");
String s = "polish";
为什么第一句话可以?难道不是吗
CaseInsensitiveString cis = "Polish";
如何使
CaseInsensitiveString
的行为类似于String
,这样上面的语句就可以了(有扩展String
和没有扩展String
)?字符串的什么特点使得它能够像这样传递一个文本?据我所知,Java中没有“复制构造函数”的概念
# 1 楼答案
文字将进入池中,s1将引用
这一次,它将检查StringPool中是否已经存在“foo”文本,以便s2引用相同的文本
首先在StringPool中创建“foo”文本,然后通过字符串arg构造函数创建字符串对象,即由于通过新操作符创建对象,因此在堆中创建“foo”,然后s3将引用它
与s3相同
所以
System.out.println(s1==s2);// **true** due to literal comparison.
和
System.out.println(s3==s4);// **false** due to object
比较(s3和s4在堆中的不同位置创建)
# 2 楼答案
字符串在java中有点特殊,它们是不可变的,所以通过引用计数来处理它们是安全的
如果你写信
然后s和t实际上引用同一个对象,s==t将返回true,因为“==”for objects read“是同一个对象”(或者,无论如何,我不确定这是否是实际语言规范的一部分,或者只是编译器实现的一个细节,所以依赖它可能不安全)
如果你写信
然后是s=t(因为您已经显式创建了一个新字符串),尽管s.equals(t)将返回true(因为字符串将此行为添加到equals)
你想写的东西
无法工作,因为您认为引用是对象的某种短路构造函数,而实际上这只适用于普通的旧java。朗。字符串
# 3 楼答案
Java字符串很有趣。看起来这些回答涵盖了一些有趣的问题。这是我的两分钱
字符串是不可变的(您永远无法更改它们)
字符串比较取决于所比较的内容
a1
不等于a2
a1
和a2
是对象引用我认为您尝试使用不区分大小写的类是错误的。别管弦乐。您真正关心的是如何显示或比较值。使用其他类格式化字符串或进行比较
即
由于您正在组成类,因此可以让比较执行您想要的操作-比较文本值
# 4 楼答案
String
在Java中是特殊的-它们是不可变的,字符串常量会自动转换为String
对象您的
SomeStringClass cis = "value"
示例无法应用于任何其他类也不能扩展
String
,因为它被声明为final
,这意味着不允许进行子分类# 5 楼答案
我相信使用文本形式(即“foo”而不是新字符串(“foo”)的主要好处是,所有字符串文本都被VM“interned”。换句话说,它被添加到池中,这样创建相同字符串的任何其他代码都将使用池中的字符串,而不是创建新实例
为了说明这一点,以下代码将打印第一行为true,第二行为false:
# 6 楼答案
String
是该语言的一个特殊内置类。它只适用于String
类,在该类中,您应该避免说因为文字
"Polish"
已经是String
类型,并且您正在创建一个额外的不必要的对象。对于任何其他类这是正确的(在这种情况下也是唯一的)做法