3

What's the logic behind making this method native?

What is the advantage over just making the interned String pool with a hash map?

It looks a little strange, but it seems like it'd be pretty easy to do in non-native code:

import java.util.HashMap;

public class String {

    // ...

    private final static HashMap<String, String> pool = new HashMap<>();

    public String intern() {

        if (pool.containsKey(this))
            return pool.get(this);

        synchronized (pool) {
            if (pool.containsKey(this))
                return pool.get(this);
            pool.put(this, this);
            return this;
        }

    }

    // ...

}

So why is it native code then?

Joseph Nields
  • 5,527
  • 2
  • 32
  • 48
  • 2
    The inner logic of `intern` is quite convoluted, in order to guarantee that it fulfills its contract in the face of all possible concurrent scenarios. It's hard enough to do in C code, trust me. (Keep in mind that a native method is no different from a regular Java method, aside from the fact that it's implemented in another language and has access to the inner workings of the JVM.) (In fact, on the JVM I worked on some native methods WERE implemented in Java -- just given special privileges.) – Hot Licks Jul 17 '15 at 23:58
  • @HotLicks I'd say it's easy in Java code, though. So why make it native? There's no performance increase, [that's for sure](http://stackoverflow.com/questions/10624232/performance-penalty-of-string-intern). – Joseph Nields Jul 18 '15 at 00:06
  • Unless someone who was in the design process of Java posts an answer, your question is answerable in any definitive manner. – jdphenix Jul 18 '15 at 00:15
  • Maybe this question can help? http://stackoverflow.com/questions/7263399/why-is-string-intern-so-slow?rq=1 – xp500 Jul 18 '15 at 00:18
  • @JosephNields - You don't know what the synchronization complexities are. – Hot Licks Jul 18 '15 at 01:31
  • 1
    @jdphenix - I wrote the C code for `intern` in the IBM AS400/iSeries JVM. It's complicated. – Hot Licks Jul 18 '15 at 01:38
  • @HotLicks what complicates it? – Joseph Nields Jul 18 '15 at 01:54
  • @JosephNields - Synchronization. Not only with objects being created in multiple threads simultaneously, but also with GC running. – Hot Licks Jul 18 '15 at 02:01
  • @HotLicks ah, yes, because interned threads are still eligible for GC – Joseph Nields Jul 18 '15 at 02:02
  • @JosephNields - Interned *Strings*. – Hot Licks Jul 18 '15 at 02:03
  • @HotLicks derp. Obviously. Whoops – Joseph Nields Jul 18 '15 at 02:46

1 Answers1

5

It seems like it'd be pretty easy to do in non-native code ...

You're wrong. By specification, String.intern() must interact with the constant pool, to meet the requirement that 'all literal strings are interned'. That can't be done from Java code.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • You could define things any way you like, but then it isn't Java any more. The JLS requires string literal constant pooling by the compiler. – user207421 Jul 18 '15 at 00:42
  • That's it, there. Because it _must_ be done by the compiler, because there's no other way to define what " does without opening up the language to all sorts of things that would make no sense with the bigger picture. So the strings at compile time could go nowhere _but_ somewhere native, and there you have it. – Joseph Nields Jul 18 '15 at 00:48
  • Just because interning is required does not demand that the `intern` method be native. After all, the JVM can call the `run` method of `Runnable` objects. `intern` is native because it needs to be to access the required internal resources. – Hot Licks Jul 18 '15 at 01:36