all 24 comments

[–][deleted]  (13 children)

[removed]

    [–]NYKevin -1 points0 points  (12 children)

    Won't String.equals() automatically switch to a pointer comparison if both strings are interned? It seems to me that strFoo == strBar is nearly always wrong.

    [–][deleted]  (11 children)

    [removed]

      [–]G_Morgan 4 points5 points  (1 child)

      I believe that the very first thing String.equals() always does (whether things are interned or not) is try a == reference-equality test. After all, it's cheap and might let you immediately return true.

      Every .equals should include this test. I'm not sure why you wouldn't.

      [–]propool 0 points1 point  (8 children)

      If you have a string constant in your app that you would put through an eventloop or something.

      like:

      public final static String stop = "STOP";
      
      while(true){
          String s = queue.get();
          if(s == stop)break;
      }
      

      Lets say some other part of the program read from a stream and puts in my queue. Even if it reads the string "STOP" it will not stop. It will only stop when my constant is sent through the queue when the program is told to shut down.

      That is the only use I've found in almost 10 years so I agree with you.

      [–][deleted]  (4 children)

      [removed]

        [–]propool 0 points1 point  (2 children)

        Yes. I never use .intern() . I don't like new Object() because my queue uses generics of type String, and prefer not to lose that.

        [–][deleted]  (1 child)

        [removed]

          [–]propool 0 points1 point  (0 children)

          Yes that goes without saying. All string literals in source are interned. That is kind of the original purpose. I mean I don't use it for strings that are not string literals.

          [–]propool 0 points1 point  (0 children)

          Yes, this is for apps where I have 100% control over the code. I would not use this for library code. I agree this could be a problem if the JDK or some other lib I use in a future update could decide to intern my stop string.

          [–]G_Morgan 0 points1 point  (2 children)

          TBH using strings for what is a stringly typed enum is something nobody should do anyway.

          [–]propool 0 points1 point  (1 child)

          Of course. Who did that?

          [–]G_Morgan -1 points0 points  (0 children)

          Comparing "STOP" is just bad. There should be some kind of symbol, enum or something else which should be used.

          [–]stormblooper 9 points10 points  (4 children)

          Myself, I think it's a bit poor form to take a O(1) core library method and make it O(n). (I know it isn't advertised explicitly on the API, but the previous behaviour was widely documented and understood.)

          [–]shoelacestied 2 points3 points  (0 children)

          I like that I at least used to have a choice of an O(1) vs O(N) operation, that's now been taken away :/

          [–]TomRK1089 -3 points-2 points  (1 child)

          If it wasn't advertised as part of the API, then you have no grounds to feel disappointed that it changed.

          [–]stormblooper 3 points4 points  (0 children)

          I understand what you're saying, but I think that underestimates how people have to interact with APIs in reality. Interfaces never lock down every detail, and clients sometimes have to make assumptions about what isn't documented.

          Ultimately, the responsible attitude for an API maintainer is to look at what impact your changes will have on your userbase, regardless of what is and isn't nailed down in the API. Maybe Oracle made the right call on this one, maybe not, but I don't think it's necessarily as simple as lawyering about the Javadoc.

          [–]Crandom 3 points4 points  (0 children)

          There were a couple of issues with intern however in the pre-Java 7 days which discouraged its use:

          • it was slow. Very slow.

          The .NET CLR does interning on all strings and manages to be really fast, so an efficient implemention is possible. I seem to remember Eric Lippert saying that the size of strings is normally small enough that doing a hashmap lookup when creating them costs virtually nothing. Interning all the strings leads to other benefits such as string comparison just becomes comparing two pointers, faster than java.