[英]Understanding explicit cast for String producing different results in c# and Java
我为Java 7和C#(.net 3.5)编写了一段相同的(相似的)代码,并得到了令人困惑的输出。 请帮助我理解这种行为:
Java的:
public class strTest {
public static void main(String [] s) {
String s1 = "abc";
String s2 = new String(new char[] {'a', 'b', 'c'});
System.out.println(s1 == s2); // false
System.out.println(((Object)s1) == ((Object)s2)); // false
System.out.println(s1.equals(s2)); // true
}
}
输出:false false true
C#:
namespace ConsoleApplication1
{
class Program2
{
static void Main(string[] args)
{
String s1 = "abc";
String s2 = new String(new Char[] {'a', 'b', 'c'});
Console.WriteLine(s1 == s2); // true
Console.WriteLine(((Object)s1) == ((Object)s2)); // false
Console.WriteLine(s1.Equals(s2)); // true
}
}
}
输出:真假真
我知道像String immutability和String pool这样的概念,但我想我错过了更精细的打印。
在java中:为什么它可以使用s1引用的那个为s2创建一个新的String对象? 这不是String池应该实现的吗?
您的问题有两个方面:何时创建对象,以及==
比较如何工作:
对象创建
在实习(“汇集”)方面 - 只有常量自动实现。 您可以使用Intern
/ intern
实习其他字符串,但是当您只调用将始终创建新字符串的字符串构造函数时。 (好吧,除了.NET中一个奇怪的角落案例,但我们现在可以忽略它。)
所以在你的代码中, s1
和s2
总是引用不同的对象。
对照
差异的原因是你使用==
。 C#支持用户定义的运算符重载, String
像这样重载:
public static bool operator ==(string x, string y)
它比较字符串的内容而不是引用。 因此,当您有两个类型为string
操作数时, x == y
最终会进行相等比较,而不是进行身份比较。 这就是为什么C#输出的第一行是True
。
Java 没有这种行为,这就是为什么print是false
。
当操作数类型是Object
,C#和Java都将使用引用相等性,这就是为什么在这两种情况下第二行都是false的原因。
我假设你问为什么C#说s1 == s2? 字符串比较以区分大小写的方式比较两个字符串的内容。 由于两个字符串具有相同的内容,因此它们的比较返回true。
在Java中,仅比较字符串引用,以确定两个变量是否引用相同的字符串。 他们的内容没有比较。
至于池,Java和C#都使用池(在C#中实习)来实现文字。 以编程方式创建的字符串会导致两种语言中的新实例,即使已存在池化实例也是如此。 检查String.Intern的文档以获取与您的类似的示例,其中interned字符串是与生成的字符串不同的实例,即使它们的值相同。
字符串池仅用于文字。 如果你说String s1 =“abc”; String s2 =“abc”; 只会创建一个对象。
java语言规范要求在使用'new'关键字时创建实际的新对象,不要作弊并返回内部缓存副本。
当评估类实例创建表达式(第15.9节)导致实例化类时,将显式创建新的类实例。
Interning应用于表示为文字的字符串,但是当您明确使用新的关键字时,该语言必须使您成为一个实际的新的,不同的对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.