1

In Java when we use literal string when creating a string object, I know that a new object is created in SCP (string constant pool).

Is there a way to check if a variable is in the SCP or in the heap?

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
soung
  • 1,411
  • 16
  • 33
  • *i know that a new object is created in SCP*: well, no. But seriously, why do you care? It's an implementation detail. You shouldn't care about that. – JB Nizet Dec 25 '19 at 21:36
  • It’s not possible to find out, even through reflection because String’s `intern()` method is `native`. – Bohemian Dec 25 '19 at 21:40
  • 1
    `if (a != a.intern())` then it ***wasn't*** in the string constant pool. But the `a.intern()` adds it, so afterward it is in the constant pool. – Elliott Frisch Dec 25 '19 at 21:42
  • 1
    (The dupe question chosen did not answer the questions asked here.) – Stephen C Dec 25 '19 at 22:33

1 Answers1

2

First of all, the correct term is the "string pool", not the "string constant pool"; see String pool - do String always exist in constant pool?

Secondly, you are not checking a variable. You are checking the string that some variable contains / refers to. (A variable that contains a reference to the string, cannot be be "in the SCP". The variable is either on the stack, in the heap (not SCP), or in metaspace.)

Is there a way to check if a variable is in SCP or in heap ?

  1. From Java 7 and later, the string pool is in the (normal) heap. So your question is moot if we interpret it literally.

  2. Prior to Java 7, the way to check if a String is in the string pool was to do this

    if (str == str.intern()) {
        System.out.println("In the string pool");
    }
    

    However, this had the problem that if an equivalent str was not already in the pool, you would have added a copy of str to the pool.

  3. From Java 7 onwards, the above test is no longer reliable. A str.intern() no longer needs to copy a string to a separate region to add it the string pool. Therefore the reference to an intern'd string is often identical to the reference to the original (non-interned) string.

    char[] chars = new char[]{'a', 'b', 'c'};
    String str = new String(chars);
    String interned = str.intern();
    System.out.println(str == interned);
    

    In fact str == str.intern() can only detect the case where you have a non-interned string with the same content as a string literal.

Or at least list all string instances in SCP ?

There is no way to do that.


As JB Nizet pointed out, there is really not a lot of point in asking these questions:

  • You shouldn't be writing code that depends on whether a string is in the string pool or not.
  • If you are concerned about storage to the level where you would contemplate calling intern for yourself, it is better to make use of the opportunistic string compaction mechanism provided by Java 9+ garbage collectors.
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216