Timeless
Timeless

Reputation: 7547

Why does String == "" return false in Java but not in C#?

I have a simple recursive method written in both Java and C#

Java

public static String reverse(String letter) {
    if (letter == "")
        return "";
    else
        return letter.substring(letter.length() - 1)
                + reverse(letter.substring(0, letter.length() - 1));
}

C#

public static string reverse(string letter)
{
    if (letter == "")
        return "";
    else
        return letter[letter.Length - 1]
                + reverse(letter.Substring(0, letter.Length - 1));
}

But the Java version fails at letter == "", it returns false even if the letter is empty. Why does the C# version work while the Java version fails?

Upvotes: 1

Views: 606

Answers (9)

Douglas
Douglas

Reputation: 54897

In both C# and Java, the == operator checks for reference equality by default.

However, in .NET, the == operator is overloaded for the string type to check for value equality instead:

public static bool operator ==(string a, string b)
{
    return string.Equals(a, b);
}

Another factor you need to take into account when using both languages is string interning, which can cause even reference equality to succeed for strings that might appear distinct. From MSDN (for C#):

The common language runtime conserves string storage by maintaining a table, called the intern pool, that contains a single reference to each unique literal string declared or created programmatically in your program. Consequently, an instance of a literal string with a particular value only exists once in the system.

For example, if you assign the same literal string to several variables, the runtime retrieves the same reference to the literal string from the intern pool and assigns it to each variable.

String interning is applied across both Java and C#, and typically gives consistent results. For example, both languages evaluate string concatenation at compile-time, meaning that "a" + "b" is stored as "ab":

"ab" == "a" + "b"                                      // Java: Gives true
object.ReferenceEquals("ab", "a" + "b")                // C#:   Gives true

However, when getting a zero-length substring, only C# returns the interned empty string:

"" == "abc".substring(0, 0)                            // Java: Gives false
object.ReferenceEquals("", "abc".Substring(0, 0))      // C#:   Gives true

Upvotes: 6

Bhesh Gurung
Bhesh Gurung

Reputation: 51030

In Java,

the == operator compares the values in the variables.

So, in case of primitive type variables it will work because the values in the variables are actual values of the primitives.

e.g.

 int a = 1;
 int b = 2;

 if(a == b) { 

In the above it is doing what you think it's doing.


But, in case of reference type variables, the values in the variables are the references to the objects that they are pointing to.

So, if you want to do an identity check (i.e. you want to see if two different variables are pointing to the same object) then you have to use ==. Which will return false if the variables have reference to two different objects (the contents of the objects being same is not relevent).

But, if what you are trying to campare is the contents of the objects then you have to use equals method (but you have to make sure that the equals method has been implemented properly).

e.g.

String a = "a";
String b = new String("a");

if(a == b) { //... identity check (returns false)

//...

if(a.equals(b)) { //... comparing the contents (returns true)

Upvotes: 1

Tooraj Jam
Tooraj Jam

Reputation: 1612

Several ways to do this:

  1. For comparing Strings in Java we have to use .equals() or .equalsIgnoreCase() methods. ... if (letter.equals("")) { ...
  2. Checking the length tells whether or not this String length is 0. ... if (letter.length() == 0) { ...
  3. There is am equivalent for (letter.length() == 0) in Java. That is .isEmpty() method.

BTW:
Don't forgot to if (letter == null).

Upvotes: 3

ams
ams

Reputation: 25599

In java == compares whether two variables contain the same object. The constant "" will probably always be a different instance of String, even though both instances may contain the same string value.

If you want to compare the contents of the object then, in the case of String, you can do it like this:

letter.equal("")

Upvotes: 2

Rahul
Rahul

Reputation: 77906

You should use equals method like letter.equals("") since equality operator (==) ultimately compare reference of the object and not the value.

Also, for C# a better practice would be to use string.Empty instead "" like

if (letter == string.Empty)

Upvotes: 0

james_bond
james_bond

Reputation: 6906

'Cause you're comparing references, use String.equals or String.equalsIgnoreCase

Upvotes: 0

Dancrumb
Dancrumb

Reputation: 27559

A String is an object.

When you use ==, you are doing an identity comparison. This means that a == b is asking whether a and b are the same object.

The variable letter and the constant object "" are not the same object, so you get false.

Instead, you should be using:

letter.equal("")

This is asking if the letter object has a value equal to "", which is what you mean to ask.

Upvotes: 4

Clément
Clément

Reputation: 324

== works for String objects((look for string pool java in google), but you should (and must) REALLY use .equals().

Upvotes: -1

UmNyobe
UmNyobe

Reputation: 22910

Because for objects the operator == test for equality of references. You must always use equals

Upvotes: 5

Related Questions