0

I have found a strange behavior of assertions in Java (Eclipse). Easy example: If i execute this...

public static void main (String[] args) {
    assert(getA() == "a") : "Invalid";
    System.out.println("Assertion successful!");
}

private static String getA() 
{
    return "a";
}

... it will show me "Assertion successful!" as it should. However if i try this...

public static void main (String[] args) {
    assert(getA() + "b" == "ab") : "Invalid";
    System.out.println("Assertion successful!");
}

private static String getA() 
{
    return "a";
}

... I get an AssertionError. How come this Assertion doesn't return true?

Note:

Community
  • 1
  • 1
Pascal Weber
  • 557
  • 3
  • 11
  • 19
  • 2
    http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java – assylias Mar 19 '13 at 16:19
  • The real question is: why doesn't the first snippet print "Invalid"? – sp00m Mar 19 '13 at 16:21
  • 1
    It has to do with an optimization in the JVM sp00m, in the first case the "a" literal each occupy the same memory space – Cruncher Mar 19 '13 at 16:21
  • when comparing Objects use Object.equals(Object o), == basically tests if the entities you are comparing are instances of the same Object – John Kane Mar 19 '13 at 16:22
  • 1
    @sp00m: see Javiers answer.. oh man, I should better get more sleep^^ – Pascal Weber Mar 19 '13 at 16:22
  • @John Kane: == tests whether or not 2 objects are the same object (occupy the same place in memory) not if they have the same type – Cruncher Mar 19 '13 at 16:24
  • 2
    If you think some core java function or library is behaving "weirdly" like assert. It is 99.999% of the time user error :) – cowls Mar 19 '13 at 16:24
  • @Cruncher yeah, sorry I should have explained that better. Instances of the same Object would be in the same memory location. I didnt mean to imply type. Thank you for pointing that out though. – John Kane Mar 19 '13 at 17:09

2 Answers2

6

You need to give

"a".equals(getA());

Second case

"ab".equals("b".concat(getA()));

Reason:- == is for comparing object references, whereas equals() is used for the string value comparison, which is what you needed. Plus, the first scenario had the same string literal "a", hence, it returned true. But in the second case, a new instance of String was created for getA()+b , which is different from the literal "ab".

Rahul
  • 44,383
  • 11
  • 84
  • 103
  • Beat me to it lol. When you do == it does object compare opposed to string value comparison. This can lead to strange comparisons. – Cruncher Mar 19 '13 at 16:19
  • Oh noes, that was it! Thank you, that was embarrassing! :D – Pascal Weber Mar 19 '13 at 16:20
  • well, what about this example here? why does this fail? http://pastebin.com/ZgA6bTjw – Pascal Weber Mar 19 '13 at 16:26
  • @RomanMächler In that example you are comparing two string arrays... completely different case. See this link for the answer to that question: http://stackoverflow.com/questions/8777257/equals-vs-arrays-equals-in-java – cowls Mar 19 '13 at 16:31
  • 1
    np, I think a variation of this question appears at least once a day on SO :) – cowls Mar 19 '13 at 16:34
5

"a" is a literal on compile time, then "a"=="a" evaluates as true

getA()+"b" creates a new instance of String, which is different from the compile time literal "ab"

Javier
  • 12,100
  • 5
  • 46
  • 57