Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding explicit cast for String producing different results in c# and Java

Tags:

java

c#

I wrote a same(..similar?) piece of code for Java 7 and C#(.net 3.5) and got a confusing output. Please help me in understanding this behavior:

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
    }
}

Output : 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
        }
    }
}

Output : True False True

I am aware of concepts like String immutability and String pool but I guess I am missing the finer print.

In java: Why did it create a new String object for s2 when it could have used the one which is referenced by s1? Isn't that what String pool is supposed to achieve?

like image 543
thisdotnull Avatar asked May 17 '26 07:05

thisdotnull


1 Answers

There are two aspects to your question: when objects are created, and how == comparisons work:

Object creation

In terms of interning ("pooling") - only constants are interned automatically. You can intern other strings using Intern/intern, but when you just call the string constructor that will always create a new string. (Well, except for one bizarre corner case in .NET, but we can ignore that for now.)

So in your code, s1 and s2 always refer to different objects.

Comparison

The cause of the difference is your use of ==. C# supports user-defined operator overloading, and String overloads it like this:

public static bool operator ==(string x, string y)

which compares the contents of the string rather than the references. So when you have two operands of type string, x == y ends up doing an equality comparison rather than an identity comparison. That's why the first line of the C# output is True.

Java doesn't have this behaviour, which is why is prints false.

When the operand types are Object, both C# and Java will use reference equality, which is why the second line is false in both cases.

like image 198
Jon Skeet Avatar answered May 19 '26 20:05

Jon Skeet