• (nodebb)

    It an object casts like a string and reflects like a string, then it's most likely a string.

  • Jaloopa (unregistered)
    private boolean isString(string s){ return true;}
    
    private boolean isString(Object o){ return false;}
    

    There. No reflection required.

  • (nodebb)

    I'd bet this was written by someone who didn't understand generics, so they typed everything as 'Object', and used reflection to do everything.

  • Naomi (unregistered)

    Actually, Java generics are checked at compile time. You can break it, if you really want to, with unchecked casts, but saying that you "lose any compile-time safety" because of it is like saying C++ doesn't have any compile-time safety because you can do unsafe things with pointers.

    Also, String is final (equivalent to C#'s sealed keyword - Java's sealed keyword does something else entirely), so polymorphism isn't a concern. The instanceof keyword is more appropriate than isAssignableFrom since we have an instance of the class here.

  • Naomi (unregistered) in reply to Jaloopa

    This won't work. Overloads are resolved at compile time, not runtime.

  • Naomi (unregistered)

    I'm not sure what you mean (I think there's a word or two missing in your comment), but your suggestion is the right way to do it:

    private static boolean isString(Object o) {
        return o instanceof String;
    }
    

    It's technically true that Java doesn't have a unified type system since primitives aren't objects, but due to auto-boxing, it barely matters; anything can be assigned to Object. assert !isString(4); compiles and holds at runtime. (None of this is relevant here since String isn't a primitive type.)

  • (nodebb)

    What you're looking for in Java would be return o instanceof String. Which would also catch the theoretical (but impossible because its final) subclasses of String.

    Somehow the co-worker is someone who doesn't know instanceof exists but does know about reflection in Java. Which sounds like they might have some fun code to debug.

  • Jaloopa (unregistered) in reply to Naomi

    Good point. OK

    private boolean isString(Object o){
        try{
            string s = (string)o;
            return true;
        }
        catch{
            return false;
        }
    }
    
  • Mirror, Mirror (unregistered)

    As a (former) Java dev, most of my fondest memories in Java involve reflection.

    I had one internal tool which scanned a particular path for classes related to a document we needed to import. The class would define what data was stored in that particular part of the file and how to upload it to our system. The document parts could change year over year and we needed to also continue supporting previous years, so adding classes is a yearly task.

    We had another application which also pulled in a number of small documents for processing in or out. They shared a generics based dao, which the app injected with Guice. Now, the issue is that you need(ed) to define each sub type for the Guice injection. This leads to a long file of declaring the same dao with all the sub-types, which also has the 'feature' of being a magic file that you just have to know about or you'll get runtime errors that only show up for the one sub-type you forgot about and only when you use it. I used reflection to handle the Guice set-up at application start-up, which saved from the magic file AND let you know if you forgot when you start the application rather than mid-testing that specific document's code.

    The third (and final) was when we had to do a data provider migration. We wanted to know which data points in our 50+ parameter god object (before you ask, it was made before my time there) would change numbers coming out. It took a half dozen or so exceptions for e.g. pojos verses collections and such, but I was able to use a deep copy on the god object and swap pointers to it's parameters one at a time to see what was a minimum number of parameters changed that would give us the same numbers out. It gave critical information on what data points we needed to work on during an all-hands-on-deck change, and was never meant for production.

    tl;dr: I love reflection, but mainly for one-off tasks, like research or start-up.

  • Naomi (unregistered) in reply to Jaloopa

    ? Just use instanceof; there's no need to make it complicated.

  • Smithers (unregistered)

    cl.equalsIgnoreCase("java.lang.String")

    But... Java isn't case-insensitive...

    package JAVA.LANG; public class sTRING { /*Hi, I'm a string, just ask isString().*/ }

  • Airdrik (unregistered) in reply to Smithers

    :D this is exactly what I was thinking when I read through that!

  • Gregovin (unregistered)

    My question(and perhaps the real wtf) is why do you want to know if something is "really" a string or if it just can be converted into one? I would guess you either have a function which is only supposed to accept string parameters or something implementing really cursed polymorphism. If its the first then just use the type system and if its the second... it depends but this is probably an xy problem(or just convert everything to string beforehand)

  • Martin Tilsted (unregistered)

    And for the real fun implementation:

    private boolean isString(Object o){ return o==o.toString(); // Think about why this works :) }

  • (nodebb) in reply to Jaloopa

    FTFY

    private boolean isString(Object o){
        try{
            String s = (String)o;
            return true;
        }
        catch(java.lang.ClassCastException e {
            return false;
        }
        catch {
            return FileNotFound;
        }
    }
    

    Addendum 2024-05-13 07:10: Syntax error on line 6

  • kaejo (unregistered) in reply to Martin Tilsted

    That's a clever version :-)

  • Pieroxy (unregistered)

    The String class is final in Java and thus cannot be extended.

Leave a comment on “Reflect on Your Mistakes”

Log In or post as a guest

Replying to comment #:

« Return to Article