1

I have some confusion about the usefulness of the intern() method.

This line of code can clear my confusion:

String a = new String("abc").intern();

How many objects will the above line of code create? If it will create an object in heap memory as well as string pool memory then how is the intern() method increasing performance?

khelwood
  • 55,782
  • 14
  • 81
  • 108
parichay07
  • 45
  • 5
  • 3
    "i have some confusion about the usefulness of intern() method" The simple solution to your confusion is not to use it. I'm not being snarky: it's *rarely* useful. – Andy Turner May 07 '19 at 10:15
  • 2
    The example you have given is not useful, since `String a = "abc";` would already be interned. – khelwood May 07 '19 at 10:16
  • Why do you think it is increasing performance? – talex May 07 '19 at 10:22
  • Interning string decrease memory usage, performance would probably be slightly worse. For more info check out this article: https://www.geeksforgeeks.org/interning-of-string/ . However, I'd say it is barely ever useful. – Amongalen May 07 '19 at 10:25
  • yes @khelwood i know that i can use String a = "abc"; this is the origin of my confusion.why do we even store string object in heap memory??as storing it in string pool will be more efficient as for same string literal there will only be one object created for all of them. – parichay07 May 07 '19 at 10:25
  • 1
    @parichay07 You would not do this. The example you give is something no one should do. – khelwood May 07 '19 at 10:31

2 Answers2

2

How many objects will the above line of code create?

  • The string literal is represented at runtime by one String object. If that object hasn't yet been created, it may be created (lazily) by the execution of this statement. In either case, the object representing the literal will have been interned. (The number of String objects that are created in this process is an implementation detail that depends on the Java version. Yes, really.)

  • The new String(...) creates an object each time you do it.

  • Since the original String o bject was interned, the intern() call will return that object; i.e. the String that represents the string literal: the one you started with.

So, in summary, your code may lead to the creation of up to three objects, directly and behind the scenes, but the object created by the new will be unreachable by the end of the statement.

Indeed, since,

String a = new String("abc").intern();

and

String a = "abc";

give identical results, the new / intern sequence is complete waste of time.


If it will create an object in heap memory as well as string pool memory then how is the intern() method increasing performance?

It doesn't directly increase performance:

  • There is a potential indirect benefit if you can intern all of the strings in a data structure. Then you can use == rather than equals(Object) to test for equality.

    However, you are trading off the cost of equals versus the cost if intern, so you need to make a few object comparisons before you get a net performance win. In addition, if you forget to intern one of the strings, == is liable to give you a different answer to equals. (That's probably a bug!)

  • In older JVMs, there is a potential indirect benefit if you have a lot of long-lived String objects. Using intern to de-dup will reduce long-term memory usage and reduce long-term GC costs.

    However, in recent JVMs the GC will automatically de-dup String objects that survive a few GC cycles. Since this only applies to relatively long-lived objects, this is a more efficient way to de-dup. And the process is transparent to the application!

In short, under most circumstances there are no advantages and significant disadvantages to using the intern() method in application code. Leave it alone.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

You will have two strings:

  • "abc" - The string literal. It adds also "abc" to the string pool (see later)
  • new String("abc") - A new copy of "abc" created explicitly with the new operator

Note that nothing happens for the call of intern because the string "abc" is already present in the string pool since the declaration of the string literal.

Also the assignement doesn't create any new object.

The method intern:

Returns a canonical representation for the string object. A pool of strings, initially empty, is maintained privately by the class String. When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true. All literal strings and string-valued constant expressions are interned. String literals are defined in section 3.10.5 of the The Java™ Language Specification.

In this context the call to intern does nothing useful so you will not have any increase of performances.

Davide Lorenzo MARINO
  • 26,420
  • 4
  • 39
  • 56