可以从非空的 UTF-8 字节数组创建空的 java 字符串吗?

Can a empty java string be created from non-empty UTF-8 byte array?

提问人:Steve Armstrong 提问时间:5/7/2009 最后编辑:Steve Armstrong 更新时间:5/8/2009 访问量:3674

问:

我正在尝试调试某些内容,我想知道以下代码是否可以返回 true

public boolean impossible(byte[] myBytes) {
  if (myBytes.length == 0)
    return false;
  String string = new String(myBytes, "UTF-8");
  return string.length() == 0;
}

我可以传入一些将返回 true 的值吗?我已经摆弄了只传入 2 字节序列的第一个字节,但它仍然产生一个字符串。

澄清一下,这发生在 Java 1.4 上的 PowerPC 芯片上,该代码通过 GCJ 编译为本机二进制可执行文件。这基本上意味着大多数赌注都关闭了。我主要想知道 Java 的“正常”行为或 Java 的规范是否做出了任何承诺。

java 字符串 utf-8

评论


答:

0赞 skaffman 5/7/2009 #1

UTF-8 是一种可变长度编码方案,大多数“正常”字符是单字节。因此,任何给定的非空 byte[] 将始终转换为字符串,我想。

如果你想玩它说,写一个单元测试,它遍历每个可能的字节值,传入该值的单值数组,并断言字符串是非空的。

7赞 Trey 5/7/2009 #2

根据 java.util.String 的 javadoc,当 bytearray 包含无效或意外数据时,不会指定 new String(byte[], “UTF-8”) 的行为。如果希望生成的字符串具有更高的可预测性,请使用 http://java.sun.com/j2se/1.5.0/docs/api/java/nio/charset/CharsetDecoder.html

1赞 Glen 5/7/2009 #3

可能。

来自 Java 5 API 文档“当给定字节在给定字符集中无效时,此构造函数的行为是未指定的。

我想这取决于: 您使用的是哪个版本的 java 哪个供应商编写了您的 JVM(Sun、HP、IBM、开源 JVM 等)

一旦文档显示“未指定”,所有赌注都关闭了

编辑:被 Trey 击败 听听他关于使用 CharsetDecoder 的建议

1赞 Esko Luontola 5/7/2009 #4

如果 Java 正确处理了 BOM 标记(我不确定他们是否已经修复了它),那么应该可以只输入一个带有 BOM 的字节数组(U+FEFF,在 UTF-8 中是字节序列 EF BB BF)并得到一个空字符串。


更新:

我用 1-3 个字节的所有值测试了该方法。在 Java 1.6 上,它们都没有返回空字符串。以下是我用于不同字节数组长度的测试代码:

public static void main(String[] args) throws UnsupportedEncodingException {
    byte[] test = new byte[3];
    byte[] end = new byte[test.length];

    if (impossible(test)) {
        System.out.println(Arrays.toString(test));
    }
    do {
        increment(test, 0);
        if (impossible(test)) {
            System.out.println(Arrays.toString(test));
        }
    } while (!Arrays.equals(test, end));

}

private static void increment(byte[] arr, int i) {
    arr[i]++;
    if (arr[i] == 0 && i + 1 < arr.length) {
        increment(arr, i + 1);
    }
}

public static boolean impossible(byte[] myBytes) throws UnsupportedEncodingException {
    if (myBytes.length == 0) {
        return false;
    }
    String string = new String(myBytes, "UTF-8");
    return string.length() == 0;
}

评论

0赞 Alan Moore 5/8/2009
不幸的是,Java 无法正确处理 UTF-8 BOM。根本不处理它,真的;只是将其视为内容的一部分