【问题标题】:Java String internal representationJava 字符串内部表示
【发布时间】:2016-05-04 02:08:20
【问题描述】:

我了解 Java 对 String 的内部表示是 UTF-16. What is java string representation?

另外,我知道在 UTF-16 字符串中,每个“字符”都使用一个或两个 16 位代码单元进行编码。

但是,当我调试以下 java 代码时

String hello = "Hello";

变量hello是一个5字节数组0x48、0x101、0x108、0x108、0x111 这是“你好”的ASCII。

这怎么可能?

【问题讨论】:

  • 你如何调试这个?它只是一个字符数组。
  • 你确定这不是你看到的变量名吗?
  • @Fildor 0x48 具有“H”字符表示,而不是“h”。
  • @MarounMaroun 好点...
  • 你怎么知道的? IntelliJ IDEA 调试器不显示用于存储char 值的字节数。

标签: java string encoding utf-16


【解决方案1】:

String 内部表示没有指定,它是实现细节,所以你不能依赖它。很有可能在 JDK-9 中将更改为使用双重编码(Latin-1 用于可以用 Latin-1 编码的字符串,UTF-16 用于其他字符串)。有关详细信息,请参阅JEP-254。此功能已集成在 OpenJDK 主代码库中,因此如果您使用 Java-9 早期访问版本,您实际上将有 5 个字节。

【讨论】:

    【解决方案2】:

    我使用以下代码获取了一个迷你 Java 进程的 gcore 转储:

     class Hi {
        public static void main(String args[]) {
            String hello = "Hello";
            try {
                Thread.sleep(60_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    }
    

    并在 Ubuntu 上进行了 gcore 内存转储。 (使用jps 获取pid 并将其传递给gcore)

    如果发现这个:48 65 6C 6C 6F 在使用 Hexeditor 的转储中,所以它在内存中的某个位置作为 ASCII。

    还有48 00 65 00 6C 00 6C,它是StringUTF-16 表示的一部分

    【讨论】:

    • 是的,它是 ASCII(或者更确切地说是 UTF8)在编译的 .class 文件的常量池中。
    • 好吧,所以这个答案,连同@yole 上面的评论(Intellij 调试器现在有点必须显示每个字符的大小)回答了这个问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-05
    • 2015-08-09
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    相关资源
    最近更新 更多