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

时间:2009-05-07 15:37:17

标签: java string utf-8

我正在尝试调试某些东西,我想知道以下代码是否能够返回真正的

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

我能传递的某些值会返回true吗?我已经摆弄了2字节序列的第一个字节,但它仍然产生一个字符串。

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

4 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:1)

可能。

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

我猜这取决于: 您正在使用的是哪个版本的Java 哪家供应商编写了您的JVM(Sun,HP,IBM,开源的等)

一旦文档说“未指定”,所有投注均已关闭

编辑:Trey打败它 听取他关于使用CharsetDecoder的建议

答案 2 :(得分:1)

如果Java正确处理BOM mark(我不确定它们是否已修复它),那么应该可以输入一个只有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;
}

答案 3 :(得分:0)

UTF-8是一种可变长度编码方案,大多数“普通”字符是单字节。所以任何给定的非空字节[]总是会转换为字符串,我想过。

如果你想播放它,请写一个单元测试,它迭代每个可能的字节值,传入该值的单值数组,并断言该字符串是非空的。