检查变量是否在字符串常量池中 [英] Check if a variable is in the string constant pool

查看:87
本文介绍了检查变量是否在字符串常量池中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java中,当我们在创建字符串对象时使用文字字符串时,我知道在SCP(字符串常量池)中创建了一个新对象.

有没有办法检查变量是在 SCP 中还是在堆中?

解决方案

首先,正确的术语是字符串池",而不是字符串常量池";参见 字符串池 - 做字符串始终存在于常量中游泳池?

其次,您没有检查变量.您正在检查某个变量包含/引用的字符串.(包含对字符串的引用的变量不能在 SCP 中".该变量要么在堆栈中,要么在堆中(不是 SCP),要么在元空间中.)

<块引用>

有没有办法检查一个变量是在 SCP 中还是在堆中?

  1. 从 Java 7 及更高版本开始,字符串池位于(正常)堆中.因此,如果我们按字面解释,您的问题就没有实际意义.

  2. 在 Java 7 之前,检查 String 是否在字符串池中的方法是这样做

    if (str == str.intern()) {System.out.println("在字符串池中");}

    然而,这有一个问题,如果一个等效的 str 不在池中,你就会向池中添加一个 str 的副本.

  3. 从 Java 7 开始,上述测试不再可靠.str.intern() 不再需要将字符串复制到单独的区域以将其添加到字符串池中.因此,对实习字符串的引用通常与对原始(非实习)字符串的引用相同.

    char[] chars = new char[]{'a', 'b', 'c'};String str = new String(chars);字符串实习生 = str.intern();System.out.println(str == 实习);

    事实上,str == str.intern() 只能检测您有一个与字符串文字内容相同的非实习字符串的情况.

<块引用>

或者至少列出 SCP 中的所有字符串实例?

没有办法做到这一点.

<小时>

正如 JB Nizet 指出的那样,问这些问题真的没有什么意义:

  • 您不应该编写依赖于字符串是否在字符串池中的代码.
  • 如果您担心存储到您会考虑为自己调用 intern 的级别,最好利用 Java 9+ 垃圾收集器提供的机会性字符串压缩机制.立>

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?

解决方案

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.

这篇关于检查变量是否在字符串常量池中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆