• Ben (unregistered) in reply to Coyne
    Coyne:
    Nope. That's not it either. In Java, null does not have a type...

    Au contraire, there certainly is a null type, so speaketh the JLS.

    Many type systems have some sort of bottom or omega type that is the subtype of all other types. But in Java, null has a distinct type, so it's not bottom, but anything that is typed to accept a reference may also accept a null. It's an odd state of affairs.

    I'm on a terrible connection, but for TRWTF you might look up Tony Hoare's presentation on "Null References: the Billion Dollar Mistake".

  • (cs) in reply to future guy
    future guy:
    public static boolean equalsAllowNull(String s1, String s2){    
       System.out.println("strcmp 1:"+s1+" 2:"+s2);
       return (s1 != null)
          ?((s2 != null)
             ?(((String)s1).equalsIgnoreCase(((String)s2)))
             :false)
          :true;
    }
    
    Okay, someone please tell me I'm blind and I've missed something and explain why does s1==null return true? Also what's the point of casting string into string ? sure it looks cool with all those brackets, but it still hurts my eyes.

    It returns true if s1 == null because it's broken. However, since the previous version would (badly) generate an error if either argument were null, I suppose we're making progress.

    The casts to String are just there because it was copied and pasted from the earlier version. The casts were necessary in that method because the arguments were of type Object. The casts to Integer are not necessary in either version.

  • Wejn (unregistered) in reply to JavaConfig
    JavaConfig:
    Switching server farms should only involve looking at config files IMO.
    Exactly it should. The only problem? You live in the real world, not some fantasy land. ;)

    And in RW people are often lazy, stupid or under time pressure. And they sometimes hardcode stuff that shouldn't be hardcoded.

    Not a Java problem. More like "sure, I'll make that proper later" problem.

  • Yardik (unregistered) in reply to marcan
    marcan:
    TRWTF is that it's 2010 and Java still needs a method call to test for object equality. In real languages, you use == to compare objects (or at least strings) and null == null (or whatever term the language uses for null)

    You can't overload operators in java. Hence, == is not a valid comparison for anything other than object instance. Most 'real' programmers would understand that just because a language lacks a feature it does not make it less real of a language.. just different.

    Hey I like C# better, but saying java isn't a real language is just idiocy.

  • anonymousse (unregistered) in reply to Yardik
    Yardik:
    marcan:
    TRWTF is that it's 2010 and Java still needs a method call to test for object equality. In real languages, you use == to compare objects (or at least strings) and null == null (or whatever term the language uses for null)

    You can't overload operators in java. Hence, == is not a valid comparison for anything other than object instance. Most 'real' programmers would understand that just because a language lacks a feature it does not make it less real of a language.. just different.

    Hey I like C# better, but saying java isn't a real language is just idiocy.

    don't worry, he doesn't have real intelligence

  • (cs) in reply to marcan
    marcan:
    TRWTF is that it's 2010 and Java still needs a method call to test for object equality. In real languages, you use == to compare objects (or at least strings) and null == null (or whatever term the language uses for null)

    How do you suggest that object equality be implemented for user-defined types?

    In Java, null == null.

  • RandomUser423693 (unregistered) in reply to Someone You Know
    Someone You Know:
    In Java, null == null.
    Which can obviously cause problems for people who misinterpret Java's "==" operator as a value comparison, instead of the reference comparison that it is. In that light, "null == null" makes sense. (SQL "NULL IS NULL", or VB "Nothing Is Nothing".)
  • (cs)

    What's this!!!?!?! A WTF from a Java dev??? I was under the impression that all Java devs were the most "l33t" developers on the planet or at least that's what the smug b@#st@rds told me. I'm going to submit this one to MythBusters so we all can enrich our "learns".

  • Jim McGraw (unregistered) in reply to edthered
    edthered:
    kennytm:
    C:
    kennytm:
    TRWTF is whoever use "--" inside a comment tag.
    <!--
    this -- is wrong
    -->
    things here will be commented out
    -->
    
    Wtf are you talking about? "--" is quite correct inside comments (look it up!), it's supposed to separate adjacent comments from each other, not that i've ever found this useful.

    However, your having two "-->" is TRWTF...

    If it's correct than it won't break Firefox's layout. In fact, "--" is disallowed in comments in HTML 51 and XML2.

    TRWTF is specs written (by) for lazy browser vendors. --> ends a comment, not - or -- or -> or >. I should be able to put whatever I want in a comment as long as it's not <!-- or --> and the browser should render it correctly. (actually after the first <!-- any subsequent <!-- should be ignored in the same comment block)

    What would happen to block comments in java/etc. if you couldn't have a * or a / in them? Or if an extra / made the line comment not a comment?

    Uhm, except (as you read in the provided links) the reason '--' is not allowed to keep compatibility with SGML, not because somebody expected lazy programmers.

    No doubt if you desperately desired it, there would be some way to give the appearance of having two hyphens in a row within a comment....

  • ColdDed (unregistered) in reply to THG
    THG:
    Maybe if the author had heard Tom loud enough, they could've written code proofread enough.

    Maybe so, but don't look at me in that tone of voice! Then again, maybe it was intended that way to make a point which clearly goes over the head of some readers.

  • alister (unregistered) in reply to JavaConfig

    This probably should be the WTF!

  • alister (unregistered) in reply to JavaConfig
    JavaConfig:
    Wow, never did Java, but surely, to move from one server to another, developers do not need to go through each line of code. What ever happened to write once run everywhere?

    Switching server farms should only involve looking at config files IMO.

    This is the real WTF

  • Captain Normal Form (unregistered) in reply to grzlbrmft
    grzlbrmft:
    - nested ternary operators (resulting in reduced readability)

    Don't knock nested ternaries. They're great for constructing switch statements in languages that don't support them (like Perl, before 5.10 or 5.12)

    predicate_1 ? do_1 :
    predicate_2 ? do_2 :
    predicate_3 ? do_3 : 
                  handle_error
    

    Yeah, it's "tricky" the first time you see something like that. Whatever. It's a simple normal form, and it even deals with the exceptional case nicely.

  • (cs) in reply to Jim McGraw
    Jim McGraw:
    edthered:
    TRWTF is specs written (by) for lazy browser vendors. --> ends a comment, not - or -- or -> or >. I should be able to put whatever I want in a comment as long as it's not <!-- or --> and the browser should render it correctly. (actually after the first <!-- any subsequent <!-- should be ignored in the same comment block) <p>What would happen to block comments in java/etc. if you couldn't have a * or a / in them? Or if an extra / made the line comment not a comment?</div></BLOCKQUOTE></p> <p>Uhm, except (as you read in the provided links) the reason '--' is not allowed to keep compatibility with SGML, not because somebody expected lazy programmers.</p> </div></BLOCKQUOTE> <p>I remember reading somewhere that each time the parser encounters a double dash it should invert whether &gt; will stop the comment:</p> <p>before &lt;!-- comment -- more comment &gt; after before &lt;!-- comment -- more comment --&gt; still commented --&gt; after</p> <p>But HTML5 has clarified it for maximum compatibility to simply forbid a &quot;--&quot; to appear within a comment (and possible problems with ending on &quot;---&gt;&quot;);</p> <p>Talking about whether anything should be allowed in HTML: My old dialup ISP (last century) had crappy modems and if &quot;+++ATH0\n&quot; was encountered it would actually hang up!</p>
  • mathew (unregistered)

    Looks to me like the work of a Lisp programmer who was upset that he had to work with Java, and decided to try and turn it into Lisp...

  • Aussie Contractor (unregistered) in reply to JavaConfig
    JavaConfig:
    Wow, never did Java, but surely, to move from one server to another, developers do not need to go through each line of code. What ever happened to write once run everywhere?

    Switching server farms should only involve looking at config files IMO.

    We just finished our server farm migration.

    It went like this.

    1. copy files to other server
    2. update db config on with new farm name.
    3. update virtual server name with which end users identify and connect to the application to point to the new server farm
    4. DO NOT FOR THE LOVE OF GOD AND MANKIND MAKE A CODE CHANGE, FOR ANY REASON, BETWEEN THE OLD AND NEW SYSTEMS

    I guess the key point here is "recently joined a team", "His first task was" and "After a few days" do not add up to a migration expert.

  • user unknown (unregistered)

    The rWtf is, that in each version, comparisions compare s1.equals (s1).

    Of course nobody sees it in all that casting-rubbish.

    And the first version fails for every null-value very noisy, which implies, it never hit a null value, which means, the whole thing is useless trash.

    It fails for it's most easy main purpose. WTF!

  • Burpy (unregistered)

    Well it's unusual to see ternary operators in the daily WTF. People here have usually barely heard of simple 'if' statements.

    Anyway, I think the real WTF is writing a Java client. It's a bit like trying to paint a Photorealism work without any brush and with mittens.

  • History Teacher (unregistered) in reply to The_Assimilator
    The_Assimilator:
    TRWTF:

    System.out.println("strcmp 1:"+s1+" 2:"+s2);

    This is what happens when you let bad C programmers use Java - they try to make Java behave the way they're used to, as opposed to learning to work with it, and write the stupidest, shittiest code as a result.

    Another symptom of this: writing error messages to the console instead of throwing an exception when you get unexpected input.

    Not exactly. This is what happens when you make any C programmer use Java for production code, without actually learning Java first. Being good or bad C programmer doesn't really enter into it.

    Funny thing though, a bad C programmer may well become a decent Java programmer, once he learns to give up trying to (and, being bad C programmer, usually failing to) manage all the low-level stuff you have to manage with C, and can actually concentrate on the task at hand... ;-)

  • ha (unregistered)

    TRWTF is that they should use apache common-lang library which already have this and a lot of other usefull functions.

  • Lord0 (unregistered) in reply to Rick
    Rick:
    This common problem and many like them have already been solved. http://commons.apache.org/lang/

    public static boolean StringUtils.equalsIgnoreCase(String str1, String str2)

    Its 2010, people. TRWTF is thinking that you have to write this method yourself.

    This ^^

  • Java Refugee (unregistered) in reply to RandomUser423693
    RandomUser423693:
    Someone You Know:
    In Java, null == null.
    Which can obviously cause problems for people who misinterpret Java's "==" operator as a value comparison, instead of the reference comparison that it is. In that light, "null == null" makes sense. (SQL "NULL IS NULL", or VB "Nothing Is Nothing".)

    It also overlooks the fact that if fed strings it does a case insensitive comparison. "foo" != "FOO"

  • (cs) in reply to Java Refugee
    Java Refugee:
    RandomUser423693:
    Someone You Know:
    In Java, null == null.
    Which can obviously cause problems for people who misinterpret Java's "==" operator as a value comparison, instead of the reference comparison that it is. In that light, "null == null" makes sense. (SQL "NULL IS NULL", or VB "Nothing Is Nothing".)

    It also overlooks the fact that if fed strings it does a case insensitive comparison. "foo" != "FOO"

    Are you talking about the code from the article? I'm not sure you can really say that it's been "overlooked" when it's explicitly noted in the comments at the top of the method.

  • Config What? (unregistered) in reply to Wejn
    Wejn:
    JavaConfig:
    Switching server farms should only involve looking at config files IMO.
    Exactly it should. The only problem? You live in the real world, not some fantasy land. ;)

    And in RW people are often lazy, stupid or under time pressure. And they sometimes hardcode stuff that shouldn't be hardcoded.

    Not a Java problem. More like "sure, I'll make that proper later" problem.

    Config files don't help much, when the production maintenance crew (aka Network Engineers) have to re-ask for the same list of config files every time... and STILL miss or screw up half of them. FACEPALM

    CAPTCHA: 'jugis', sheza gotta nice setta jugis

  • Jay (unregistered) in reply to Markp
    Markp:
    Jay:
    Testing o2 against null is not necessary for any of the standard classes, which will cleanly return false if the value compared against is null. But you can't necessarily be sure about user-defined classes.

    Who the hell cares about user-defined classes with bugs in them? If they want your function to work with them, they can conform to the specification for equals, which explicitly states that anyNotNullRef.equals(null) must return false.

    I stand corrected. I had forgotton that was part of the contract on equals.

  • Jay (unregistered) in reply to marcan
    marcan:
    TRWTF is that it's 2010 and Java still needs a method call to test for object equality. In real languages, you use == to compare objects (or at least strings) and null == null (or whatever term the language uses for null)

    TRWTF is that it's 2010 and Java still needs a method call to test for object equality. In my favorite language, you use == to compare objects (or at least strings) and null == null (or whatever term the language uses for null). Any language that doesn't look exactly like my favorite language is, of course, useless trash and not a real language.

    There, fixed that for you.

    If == did a value compare, then how would we compare whether two references referred to the same object? I suppose we could have another function for this, but it's not clear that the choice of the designers of Java to make == the reference compare and equals() the content compare is an obviously bad one.

  • buddyglass (unregistered) in reply to fnord

    [quote user="fnord"].

    public static boolean equalsAllowNull(String s1, String s2){
        return (s1 == null && s2 == null) || (s1 != null && s1.equalsIgnoreCase(s2));
    }
    
    [quote]

    I actually prefer the ternary operator version here:

    public static boolean equalsAllowNull(String s1, String s2) {
        return s1 == null ? s2 == null : s1.equalsIgnoreCase(s2);
    }
    

    Of course, the original code accepted Objects, meaning the caller may want the method to return "false" when the two objects passed in aren't comparable.

  • Anonymous (unregistered) in reply to Jay

    I'll try to get this argument back to objective grounds. Probably to no avail, though.

    Jay:
    If == did a value compare, then how would we compare whether two references referred to the same object?
    Simple. With a dedicated operator, e.g. "is".
    I suppose we could have another function for this, but it's not clear that the choice of the designers of Java to make == the reference compare and equals() the content compare is an obviously bad one.

    First, since Java doesn't support operator overloading, there WAS no other choice than to make it behave this way.

    Second, there a two common issues with this choice:

    • In my experience, the cases where you really want to check for object identity are very rare. Testing for equality is much more common, and should therefore be rewarded the shorter syntax.
    • For the simple types, == actually works as equality check. This semantic gets lost as soon as you 'upgrade' to objects. Overlooking this is probably the most common beginners mistake in Java. (Another case is when you change an interface from long to Long and believe that autoboxing will relieve you from changing the code.)
  • (cs) in reply to Anonymous
    Anonymous:
    - For the simple types, == actually works as equality check. This semantic gets lost as soon as you 'upgrade' to objects. Overlooking this is probably the most common beginners mistake in Java.

    True, but the reason people make this mistake is, I think, because they're not taught the language properly. Take something like:

    Integer d = new Integer(8675309);

    A lot of the educational material on the Java language will tell you that the variable called "d" now holds an object of type Integer. It doesn't. It holds a reference to an Integer. So if you then say:

    Integer e = new Integer(8675309);

    Does d == e? No. That's very easy to understand if you know that d and e are references to objects, not objects. If people were taught this when they learned the language, this would all be a lot less confusing.

  • ghquiet (unregistered)

    The master of the world, only you know The secret of a world, only you know www.coolcoachbags.com

  • Rhialto (unregistered) in reply to Zemm
    Zemm:
    I remember reading somewhere that each time the parser encounters a double dash it should invert whether > will stop the comment:

    before <!-- comment -- more comment > after before <!-- comment -- more comment --> still commented --> after

    But HTML5 has clarified it for maximum compatibility to simply forbid a "--" to appear within a comment (and possible problems with ending on "--->");

    This stems from SGML, where you have

    <! -- comment -- not a comment -- comment -->

    because you can have lots of other things appear between <! and >, in DTDs. See for example http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.3.1

  • Fabiano (unregistered) in reply to PS

    @PS

    Hi, perhaps there is an issue with the second version in the String compare.

    public static boolean equalsAllowNull(String s1, String s2){    
       System.out.println("strcmp 1:"+s1+" 2:"+s2);
       return (s1 != null)
          ?((s2 != null)
             ?(((String)s1).equalsIgnoreCase(((String)s2)))
             :false)
          :true;
    }
    

    In fact, the guy is going to do a println by adding Strings which may be null references. I suppose this should give a null execption first than null checks are done. The null case for Sting compare method is not going to be managed.

    Am I right?

  • (cs) in reply to Fabiano
    Fabiano:

    In fact, the guy is going to do a println by adding Strings which may be null references. I suppose this should give a null execption first than null checks are done. The null case for Sting compare method is not going to be managed.

    Am I right?

    Nope. In Java, concatenating a String and a null reference does not result in a NullPointerException.

    String concatenation of an Object effectively calls String.valueOf(Object) on that Object. As noted in the documentation, that method returns the String "null" if its argument is null. Try it.

  • Bikkart (unregistered)

    public static boolean equalsAllowNull(Object o1, Object o2){
    return (o1 == null) ? o2==null : (o1 instanceof String) ? ((String)o1).equalsIgnoreCase((String)o2) //thows ClassCastException if o2 is not String : o1.equals(o2); }

  • Fabiano (unregistered) in reply to Someone You Know

    @by Someone You Know Thanks for pointing, I have thought, in this case, the Object is already a String... I fear String.valueoF is not going to be called. I have to try this immediatly.

  • Fabiano (unregistered) in reply to Fabiano

    @by Someone You Know

    You are absolutely right! I have tried in Netbeans and it as worked exactly as you pointed.

    Thanks for pointing.It looks quite strange String.valueOf() applies to String objects too.

  • (cs) in reply to Fabiano
    Fabiano:
    @by Someone You Know

    You are absolutely right! I have tried in Netbeans and it as worked exactly as you pointed.

    Thanks for pointing.It looks quite strange String.valueOf() applies to String objects too.

    Sorry, that may have been misleading. I don't know if it actually calls String.valueOf(Object).

    But the behavior, which is defined here, is the same — any null reference, String or not, is converted to the String "null".

    Bear in mind that a null reference isn't really a String, even if at some point it was assigned to a variable of type String.

  • Jim (unregistered)

    I don't think anyone found this WTF: in both the old and new equalsAllowNull() for Integers, the call to equals() tests the first Integer against itself!

    public static boolean equalsAllowNull(Integer s1, Integer s2){
       return (s1 != null)
          ?((s2 != null)
             ?(((Integer)s1).equals(((Integer)s1)))
             :false)
          :true;    
    }

    Others pointed out the problems with symmetry: if s1 is null and s2 is not null, the result is true, while if s1 is not null and s2 is null, the result is false.

    public static boolean equalsAllowNull(String s1, String s2){    
       System.out.println("strcmp 1:"+s1+" 2:"+s2);
       return (s1 != null)
          ?((s2 != null)
             ?(((String)s1).equalsIgnoreCase(((String)s2)))
             :false)
          :true;
    }

    And of course the String method has the gratuitous call to println().

  • Jim (unregistered) in reply to Jim

    Oh yeah, and the casts are now unnecessary in the new form, and you want "i1" and "i2" for the Integers.

  • Anm (unregistered) in reply to PS

    Nope. May NPE if o1 is null and o2 is not. Try this:

    public static boolean equalsAllowNull(Object o1, Object o2) {
        return (o1 != null)? o1.equals(o2): o2==null;
    }
    
    public static boolean equalsAllowNull(String s1, String s2) {
        return (s1 != null)? s1.equalsIgnoreCase(s2): s2 == null;
    }
    

    Of course, you could avoid the tertiary operators for legibility.

  • Fabiano (unregistered) in reply to Someone You Know

    I'm a bit late.. but thanks for the detailed infos

Leave a comment on “Compare.java”

Log In or post as a guest

Replying to comment #:

« Return to Article