Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
理解在c#和Java中产生不同结果的字符串的显式转换_C#_Java - Fatal编程技术网

理解在c#和Java中产生不同结果的字符串的显式转换

理解在c#和Java中产生不同结果的字符串的显式转换,c#,java,C#,Java,我为Java7和C#(.NET3.5)编写了一段相同的(…类似的?)代码,得到了一个令人困惑的输出。请帮助我理解这种行为: 爪哇: 输出:false 假的 真的 C#: 输出:真 假的 真的 我知道诸如字符串不变性和字符串池之类的概念,但我想我错过了更详细的内容 在java中:当s2可以使用s1引用的字符串对象时,为什么它要为s2创建一个新的字符串对象?这不是字符串池应该实现的吗?您的问题有两个方面:对象是何时创建的,以及比较是如何工作的: 对象创建 就内部(“池”)而言,只有常量会自动内部。您

我为Java7和C#(.NET3.5)编写了一段相同的(…类似的?)代码,得到了一个令人困惑的输出。请帮助我理解这种行为:

爪哇:

输出:false 假的 真的

C#:

输出:真 假的 真的

我知道诸如字符串不变性和字符串池之类的概念,但我想我错过了更详细的内容


在java中:当s2可以使用s1引用的字符串对象时,为什么它要为s2创建一个新的字符串对象?这不是字符串池应该实现的吗?

您的问题有两个方面:对象是何时创建的,以及比较是如何工作的:

对象创建

就内部(“池”)而言,只有常量会自动内部。您可以使用
intern
/
intern
插入其他字符串,但只要调用字符串构造函数,就会始终创建一个新字符串。(好吧,除了.NET中的一个奇怪的角落案例,但我们现在可以忽略它。)

因此,在代码中,
s1
s2
总是指不同的对象

比较

造成差异的原因是您使用了
==
。C#支持用户定义的运算符重载,并且
String
将其重载如下:

public static bool operator ==(string x, string y)
它比较字符串的内容而不是引用。因此,当您有两个
string
类型的操作数时,
x==y
将执行相等比较,而不是身份比较。这就是为什么C输出的第一行是
True

Java没有这种行为,这就是为什么打印
false


当操作数类型为Object时,C#和Java都将使用引用相等,这就是为什么第二行在这两种情况下都为false。

我假设您在问为什么C#表示s1==s2?字符串比较以区分大小写的方式比较两个字符串的内容。由于两个字符串具有相同的内容,因此它们的比较返回true

在Java中,只比较字符串引用,以确定两个变量是否引用同一个字符串。它们的内容没有进行比较


至于池,Java和C都对文本使用池(在C中实习)。以编程方式创建的字符串会产生两种语言的新实例,即使池实例已经存在。检查的documantation以获得与您类似的示例,其中插入的字符串与生成的字符串是不同的实例,即使它们的值相同。

字符串池仅用于文本。
如果您说String s1=“abc”;字符串s2=“abc”;将只创建一个对象。

java语言规范要求,当您使用“new”关键字时,将创建一个实际的新对象,并且不会欺骗和返回内部缓存副本


Interning应用于以文字表示的字符串,但当您明确使用新关键字时,该语言必须使您成为一个实际的新的、不同的对象。

请阅读格式帮助以了解未来的问题,在发布之前,使用预览查看您的问题的外观。出于好奇:C是否有一个
==
操作符来返回到
=
的标准含义,或者对对象的强制转换是唯一的方法?@JBNizet:始终存在静态
对象。ReferenceEquals(对象a、对象b)。在我看来,这样做的目的比施放更清楚。@JBNizet:不,没有这样的操作员——正如linac所说,只要打电话给
ReferenceEquals
@JonSkeet谢谢你的回答。只是出于好奇,是角盒->新字符串(新字符[0])?@PankajKohli:是的,就是这个。这很奇怪。不确定它是否真的在问题上下文中,但是+1让我在Java中发现了这一点。@Michael,谢谢,就在文章的末尾。他问为什么s1和s2有两个对象。
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
        }
    }
}
public static bool operator ==(string x, string y)